def get(self, key):
        # simplest case, field is directly set
        if key.field_name in self._fields:
            return self._fields[key.field_name]

        # parent undefined in editing runtime (I think)
        if key.scope == Scope.parent:
            # see STUD-624. Right now copies MongoKeyValueStore.get's behavior of returning None
            return None
        if key.scope == Scope.children:
            # didn't find children in _fields; so, see if there's a default
            raise KeyError()
        elif key.scope == Scope.settings:
            # didn't find in _fields; so, get from inheritance since not locally set
            if key.field_name in self._inherited_settings:
                return self._inherited_settings[key.field_name]
            else:
                # or get default
                raise KeyError()
        elif key.scope == Scope.content:
            if key.field_name == 'location':
                return self._location
            elif key.field_name == 'category':
                return self._category
            elif isinstance(self._definition, DefinitionLazyLoader):
                self._load_definition()
                if key.field_name in self._fields:
                    return self._fields[key.field_name]

            raise KeyError()
        else:
            raise InvalidScopeError(key.scope)
示例#2
0
 def set(self, key, value):
     if key.scope == Scope.children:
         self._children = value
     elif key.scope == Scope.settings:
         self._metadata[key.field_name] = value
     elif key.scope == Scope.content:
         if key.field_name == 'data' and not isinstance(self._data, dict):
             self._data = value
         else:
             self._data[key.field_name] = value
     else:
         raise InvalidScopeError(key.scope)
示例#3
0
 def delete(self, key):
     if key.scope == Scope.children:
         self._children = []
     elif key.scope == Scope.settings:
         if key.field_name in self._metadata:
             del self._metadata[key.field_name]
     elif key.scope == Scope.content:
         if key.field_name == 'data' and not isinstance(self._data, dict):
             self._data = None
         else:
             del self._data[key.field_name]
     else:
         raise InvalidScopeError(key.scope)
示例#4
0
    def set_many(self, kv_dict):
        """
        Provide a bulk save mechanism.

        `kv_dict`: A dictionary of dirty fields that maps
          xblock.DbModel._key : value

        """
        saved_fields = []
        # field_objects maps a field_object to a list of associated fields
        field_objects = dict()
        for field in kv_dict:
            # Check field for validity
            if field.field_name in self._descriptor_model_data:
                raise InvalidWriteError(
                    "Not allowed to overwrite descriptor model data",
                    field.field_name)

            if field.scope not in self._allowed_scopes:
                raise InvalidScopeError(field.scope)

            # If the field is valid and isn't already in the dictionary, add it.
            field_object = self._model_data_cache.find_or_create(field)
            if field_object not in field_objects.keys():
                field_objects[field_object] = []
            # Update the list of associated fields
            field_objects[field_object].append(field)

            # Special case when scope is for the user state, because this scope saves fields in a single row
            if field.scope == Scope.user_state:
                state = json.loads(field_object.state)
                state[field.field_name] = kv_dict[field]
                field_object.state = json.dumps(state)
            else:
                # The remaining scopes save fields on different rows, so
                # we don't have to worry about conflicts
                field_object.value = json.dumps(kv_dict[field])

        for field_object in field_objects:
            try:
                # Save the field object that we made above
                field_object.save()
                # If save is successful on this scope, add the saved fields to
                # the list of successful saves
                saved_fields.extend([
                    field.field_name for field in field_objects[field_object]
                ])
            except DatabaseError:
                log.error('Error saving fields %r',
                          field_objects[field_object])
                raise KeyValueMultiSaveError(saved_fields)
示例#5
0
 def get(self, key):
     if key.scope == Scope.children:
         return self._children
     elif key.scope == Scope.parent:
         return None
     elif key.scope == Scope.settings:
         return self._metadata[key.field_name]
     elif key.scope == Scope.content:
         if key.field_name == 'data' and not isinstance(self._data, dict):
             return self._data
         else:
             return self._data[key.field_name]
     else:
         raise InvalidScopeError(key.scope)
    def delete(self, key):
        # handle any special cases
        if key.scope not in [Scope.children, Scope.settings, Scope.content]:
            raise InvalidScopeError(key.scope)
        if key.scope == Scope.content:
            if key.field_name == 'location':
                return  # noop
            elif key.field_name == 'category':
                # TODO should this raise an exception? category is not deleteable.
                return  # noop
            else:
                self._load_definition()

        # delete the field value
        if key.field_name in self._fields:
            del self._fields[key.field_name]
    def set(self, key, value):
        # handle any special cases
        if key.scope not in [Scope.children, Scope.settings, Scope.content]:
            raise InvalidScopeError(key.scope)
        if key.scope == Scope.content:
            if key.field_name == 'location':
                self._location = value  # is changing this legal?
                return
            elif key.field_name == 'category':
                # TODO should this raise an exception? category is not changeable.
                return
            else:
                self._load_definition()

        # set the field
        self._fields[key.field_name] = value
示例#8
0
 def _retrieve_fields(self, scope, fields):
     """
     Queries the database for all of the fields in the specified scope
     """
     if scope in (Scope.children, Scope.parent):
         return []
     elif scope == Scope.user_state:
         return self._chunked_query(
             StudentModule,
             'module_state_key__in',
             (descriptor.location.url() for descriptor in self.descriptors),
             course_id=self.course_id,
             student=self.user.pk,
         )
     elif scope == Scope.content:
         return self._chunked_query(
             XModuleContentField,
             'definition_id__in',
             (descriptor.location.url() for descriptor in self.descriptors),
             field_name__in=set(field.name for field in fields),
         )
     elif scope == Scope.settings:
         return self._chunked_query(
             XModuleSettingsField,
             'usage_id__in',
             (
                 '%s-%s' % (self.course_id, descriptor.location.url())
                 for descriptor in self.descriptors
             ),
             field_name__in=set(field.name for field in fields),
         )
     elif scope == Scope.preferences:
         return self._chunked_query(
             XModuleStudentPrefsField,
             'module_type__in',
             set(descriptor.module_class.__name__ for descriptor in self.descriptors),
             student=self.user.pk,
             field_name__in=set(field.name for field in fields),
         )
     elif scope == Scope.user_info:
         return self._query(
             XModuleStudentInfoField,
             student=self.user.pk,
             field_name__in=set(field.name for field in fields),
         )
     else:
         raise InvalidScopeError(scope)
示例#9
0
    def set(self, key, value):
        if key.field_name in self._descriptor_model_data:
            raise InvalidWriteError("Not allowed to overwrite descriptor model data", key.field_name)

        field_object = self._model_data_cache.find_or_create(key)

        if key.scope not in self._allowed_scopes:
            raise InvalidScopeError(key.scope)

        if key.scope == Scope.user_state:
            state = json.loads(field_object.state)
            state[key.field_name] = value
            field_object.state = json.dumps(state)
        else:
            field_object.value = json.dumps(value)

        field_object.save()
示例#10
0
    def has(self, key):
        if key.field_name in self._descriptor_model_data:
            return key.field_name in self._descriptor_model_data

        if key.scope == Scope.parent:
            return True

        if key.scope not in self._allowed_scopes:
            raise InvalidScopeError(key.scope)

        field_object = self._model_data_cache.find(key)
        if field_object is None:
            return False

        if key.scope == Scope.user_state:
            return key.field_name in json.loads(field_object.state)
        else:
            return True
示例#11
0
    def delete(self, key):
        if key.field_name in self._descriptor_model_data:
            raise InvalidWriteError("Not allowed to deleted descriptor model data", key.field_name)

        if key.scope not in self._allowed_scopes:
            raise InvalidScopeError(key.scope)

        field_object = self._model_data_cache.find(key)
        if field_object is None:
            raise KeyError(key.field_name)

        if key.scope == Scope.user_state:
            state = json.loads(field_object.state)
            del state[key.field_name]
            field_object.state = json.dumps(state)
            field_object.save()
        else:
            field_object.delete()
示例#12
0
    def get(self, key):
        if key.field_name in self._descriptor_model_data:
            return self._descriptor_model_data[key.field_name]

        if key.scope == Scope.parent:
            return None

        if key.scope not in self._allowed_scopes:
            raise InvalidScopeError(key.scope)

        field_object = self._model_data_cache.find(key)
        if field_object is None:
            raise KeyError(key.field_name)

        if key.scope == Scope.user_state:
            return json.loads(field_object.state)[key.field_name]
        else:
            return json.loads(field_object.value)