Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions cms/djangoapps/contentstore/course_info_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ def get_course_updates(location, provided_id, user_id):
Retrieve the relevant course_info updates and unpack into the model which the client expects:
[{id : index, date : string, content : html string}]
"""
store = modulestore()
try:
course_updates = modulestore().get_item(location)
course_updates = store.get_item(location)
except ItemNotFoundError:
course_updates = modulestore().create_item(user_id, location.course_key, location.block_type, location.block_id)
course_updates = store.create_item(user_id, location.course_key, location.block_type, location.block_id)

course_update_items = get_course_update_items(course_updates, _get_index(provided_id))
return _get_visible_update(course_update_items)
Expand All @@ -52,10 +53,11 @@ def update_course_updates(location, update, passed_id=None, user=None, request_m
It will update it if it has a passed_id which has a valid value.
Until updates have distinct values, the passed_id is the location url + an index into the html structure.
"""
store = modulestore()
try:
course_updates = modulestore().get_item(location)
course_updates = store.get_item(location)
except ItemNotFoundError:
course_updates = modulestore().create_item(user.id, location.course_key, location.block_type, location.block_id)
course_updates = store.create_item(user.id, location.course_key, location.block_type, location.block_id)

course_update_items = list(reversed(get_course_update_items(course_updates)))
course_update_dict = None
Expand Down
6 changes: 4 additions & 2 deletions cms/djangoapps/contentstore/exams.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ def register_exams(course_key):
# if feature is not enabled then do a quick exit
return

course = modulestore().get_course(course_key)
store = modulestore()

course = store.get_course(course_key)
if course is None:
raise ItemNotFoundError("Course {} does not exist", str(course_key)) # lint-amnesty, pylint: disable=raising-format-tuple

# get all sequences, since they can be marked as timed/proctored exams
_timed_exams = modulestore().get_items(
_timed_exams = store.get_items(
course_key,
qualifiers={
'category': 'sequential',
Expand Down
5 changes: 3 additions & 2 deletions cms/djangoapps/contentstore/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ def get_parent_xblock(xblock):
Returns the xblock that is the parent of the specified xblock, or None if it has no parent.
"""
locator = xblock.location
parent_location = modulestore().get_parent_location(locator)
store = modulestore()
parent_location = store.get_parent_location(locator)

if parent_location is None:
return None
return modulestore().get_item(parent_location)
return store.get_item(parent_location)


def is_unit(xblock, parent_xblock=None):
Expand Down
5 changes: 3 additions & 2 deletions cms/djangoapps/contentstore/proctoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def register_special_exams(course_key):
# if feature is not enabled then do a quick exit
return

course = modulestore().get_course(course_key)
store = modulestore()
course = store.get_course(course_key)
if course is None:
raise ItemNotFoundError("Course {} does not exist", str(course_key)) # lint-amnesty, pylint: disable=raising-format-tuple

Expand All @@ -49,7 +50,7 @@ def register_special_exams(course_key):
return

# get all sequences, since they can be marked as timed/proctored exams
_timed_exams = modulestore().get_items(
_timed_exams = store.get_items(
course_key,
qualifiers={
'category': 'sequential',
Expand Down
39 changes: 22 additions & 17 deletions cms/djangoapps/contentstore/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def rerun_course(source_course_key_string, destination_course_key_string, user_i

try:
# cleanup any remnants of the course
modulestore().delete_course(destination_course_key, user_id)
store.delete_course(destination_course_key, user_id)
except ItemNotFoundError:
# it's possible there was an error even before the course block was created
pass
Expand Down Expand Up @@ -380,10 +380,11 @@ def export_olx(self, user_id, course_key_string, language):
self.status.fail(UserErrors.PERMISSION_DENIED)
return

store = modulestore()
if isinstance(courselike_key, LibraryLocator):
courselike_block = modulestore().get_library(courselike_key)
courselike_block = store.get_library(courselike_key)
else:
courselike_block = modulestore().get_course(courselike_key)
courselike_block = store.get_course(courselike_key)

try:
self.status.set_state('Exporting')
Expand Down Expand Up @@ -413,11 +414,12 @@ def create_export_tarball(course_block, course_key, context, status=None):
root_dir = path(mkdtemp())

try:
store = modulestore()
if isinstance(course_key, LibraryLocator):
export_library_to_xml(modulestore(), contentstore(), course_key, root_dir, name)
export_library_to_xml(store, contentstore(), course_key, root_dir, name)
else:
set_custom_attribute("exporting_course_to_xml_started", str(course_key))
export_course_to_xml(modulestore(), contentstore(), course_block.id, root_dir, name)
export_course_to_xml(store, contentstore(), course_block.id, root_dir, name)

set_custom_attribute("exporting_course_to_xml_completed", str(course_key))
if status:
Expand All @@ -432,11 +434,11 @@ def create_export_tarball(course_block, course_key, context, status=None):
LOGGER.exception('There was an error exporting %s', course_key, exc_info=True)
parent = None
try:
failed_item = modulestore().get_item(exc.location)
parent_loc = modulestore().get_parent_location(failed_item.location)
failed_item = store.get_item(exc.location)
parent_loc = store.get_parent_location(failed_item.location)

if parent_loc is not None:
parent = modulestore().get_item(parent_loc)
parent = store.get_item(parent_loc)
except: # pylint: disable=bare-except
# if we have a nested exception, then we'll show the more generic error message
pass
Expand Down Expand Up @@ -505,7 +507,8 @@ def sync_discussion_settings(course_key, user):
"""
Syncs the discussion settings for a course with the DiscussionsConfiguration model.
"""
course = modulestore().get_course(course_key)
store = modulestore()
course = store.get_course(course_key)
try:
discussion_config = DiscussionsConfiguration.objects.get(context_key=course_key)
discussion_settings = course.discussions_settings
Expand All @@ -519,7 +522,7 @@ def sync_discussion_settings(course_key, user):
course.discussions_settings['enable_graded_units'] = False
course.discussions_settings['unit_level_visibility'] = True
course.discussions_settings['provider_type'] = Provider.OPEN_EDX
modulestore().update_item(course, user.id)
store.update_item(course, user.id)

discussion_config.provider_type = Provider.OPEN_EDX

Expand Down Expand Up @@ -641,13 +644,14 @@ def get_dir_for_filename(directory, filename):

is_library = isinstance(courselike_key, LibraryLocator)
is_course = not is_library
store = modulestore()
if is_library:
root_name = LIBRARY_ROOT
courselike_block = modulestore().get_library(courselike_key)
courselike_block = store.get_library(courselike_key)
import_func = import_library_from_xml
else:
root_name = COURSE_ROOT
courselike_block = modulestore().get_course(courselike_key)
courselike_block = store.get_course(courselike_key)
import_func = import_course_from_xml

# Locate the uploaded OLX archive (and download it from S3 if necessary)
Expand Down Expand Up @@ -733,7 +737,7 @@ def read_chunk():
LOGGER.info(f'{log_prefix}: Extracted file verified. Updating course started')

courselike_items = import_func(
modulestore(), user.id,
store, user.id,
settings.GITHUB_REPO_ROOT, [dirpath],
load_error_blocks=False,
static_content_store=contentstore(),
Expand All @@ -757,9 +761,9 @@ def read_chunk():

if self.status.state == 'Updating' and is_course:
# Reload the course so we have the latest state
course = modulestore().get_course(courselike_key)
course = store.get_course(courselike_key)
if course.entrance_exam_enabled:
entrance_exam_chapter = modulestore().get_items(
entrance_exam_chapter = store.get_items(
course.id,
qualifiers={'category': 'chapter'},
settings={'is_entrance_exam': True}
Expand Down Expand Up @@ -1241,14 +1245,15 @@ def _scan_course_for_links(course_key):
...
]
"""
verticals = modulestore().get_items(
store = modulestore()
verticals = store.get_items(
course_key,
qualifiers={'category': 'vertical'},
revision=ModuleStoreEnum.RevisionOption.published_only
)
blocks = []
urls_to_validate = []
course = modulestore().get_course(course_key)
course = store.get_course(course_key)

for vertical in verticals:
blocks.extend(vertical.get_children())
Expand Down
24 changes: 14 additions & 10 deletions cms/djangoapps/contentstore/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,13 +638,14 @@ def find_release_date_source(xblock):
if xblock.category == 'chapter':
return xblock

parent_location = modulestore().get_parent_location(xblock.location,
revision=ModuleStoreEnum.RevisionOption.draft_preferred)
store = modulestore()
parent_location = store.get_parent_location(xblock.location,
revision=ModuleStoreEnum.RevisionOption.draft_preferred)
# Orphaned xblocks set their own release date
if not parent_location:
return xblock

parent = modulestore().get_item(parent_location)
parent = store.get_item(parent_location)
if parent.start != xblock.start:
return xblock
else:
Expand All @@ -665,13 +666,14 @@ def find_staff_lock_source(xblock):
if xblock.category == 'chapter':
return None

parent_location = modulestore().get_parent_location(xblock.location,
store = modulestore()
parent_location = store.get_parent_location(xblock.location,
revision=ModuleStoreEnum.RevisionOption.draft_preferred)
# Orphaned xblocks set their own staff lock
if not parent_location:
return None

parent = modulestore().get_item(parent_location)
parent = store.get_item(parent_location)
return find_staff_lock_source(parent)


Expand All @@ -680,12 +682,13 @@ def ancestor_has_staff_lock(xblock, parent_xblock=None):
Returns True iff one of xblock's ancestors has staff lock.
Can avoid mongo query by passing in parent_xblock.
"""
store = modulestore()
if parent_xblock is None:
parent_location = modulestore().get_parent_location(xblock.location,
revision=ModuleStoreEnum.RevisionOption.draft_preferred)
parent_location = store.get_parent_location(xblock.location,
revision=ModuleStoreEnum.RevisionOption.draft_preferred)
if not parent_location:
return False
parent_xblock = modulestore().get_item(parent_location)
parent_xblock = store.get_item(parent_location)
return parent_xblock.visible_to_staff_only


Expand Down Expand Up @@ -1116,9 +1119,10 @@ def get_subsections_by_assignment_type(course_key):
the display name of the section they are in
"""
subsections_by_assignment_type = defaultdict(list)
store = modulestore()

with modulestore().bulk_operations(course_key):
course = modulestore().get_course(course_key, depth=3)
with store.bulk_operations(course_key):
course = store.get_course(course_key, depth=3)
sections = course.get_children()
for section in sections:
subsections = section.get_children()
Expand Down
50 changes: 16 additions & 34 deletions xmodule/modulestore/django.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,44 +324,26 @@ def fetch_disabled_xblock_types():
)


# A singleton instance of the Mixed Modulestore
_MIXED_MODULESTORE = None


def modulestore():
"""
Returns the Mixed modulestore
"""
global _MIXED_MODULESTORE # pylint: disable=global-statement
if _MIXED_MODULESTORE is None:
_MIXED_MODULESTORE = create_modulestore_instance(
settings.MODULESTORE['default']['ENGINE'],
contentstore(),
settings.MODULESTORE['default'].get('DOC_STORE_CONFIG', {}),
settings.MODULESTORE['default'].get('OPTIONS', {})
)

if settings.FEATURES.get('CUSTOM_COURSES_EDX'):
# TODO: This import prevents a circular import issue, but is
# symptomatic of a lib having a dependency on code in lms. This
# should be updated to have a setting that enumerates modulestore
# wrappers and then uses that setting to wrap the modulestore in
# appropriate wrappers depending on enabled features.
from lms.djangoapps.ccx.modulestore import CCXModulestoreWrapper
_MIXED_MODULESTORE = CCXModulestoreWrapper(_MIXED_MODULESTORE)

return _MIXED_MODULESTORE


def clear_existing_modulestores():
"""
Clear the existing modulestore instances, causing
them to be re-created when accessed again.

This is useful for flushing state between unit tests.
"""
global _MIXED_MODULESTORE # pylint: disable=global-statement
_MIXED_MODULESTORE = None
mixed_modulestore = create_modulestore_instance(
settings.MODULESTORE['default']['ENGINE'],
contentstore(),
settings.MODULESTORE['default'].get('DOC_STORE_CONFIG', {}),
settings.MODULESTORE['default'].get('OPTIONS', {})
)
if settings.FEATURES.get('CUSTOM_COURSES_EDX'):
# TODO: This import prevents a circular import issue, but is
# symptomatic of a lib having a dependency on code in lms. This
# should be updated to have a setting that enumerates modulestore
# wrappers and then uses that setting to wrap the modulestore in
# appropriate wrappers depending on enabled features.
from lms.djangoapps.ccx.modulestore import CCXModulestoreWrapper
mixed_modulestore = CCXModulestoreWrapper(mixed_modulestore)

return mixed_modulestore


class XBlockI18nService:
Expand Down
7 changes: 1 addition & 6 deletions xmodule/modulestore/tests/django_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from xmodule.contentstore.content import StaticContent
from xmodule.contentstore.django import _CONTENTSTORE
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import SignalHandler, clear_existing_modulestores, modulestore
from xmodule.modulestore.django import SignalHandler, modulestore
from xmodule.modulestore.tests.factories import XMODULE_FACTORY_LOCK
from xmodule.modulestore.tests.mongo_connection import MONGO_HOST, MONGO_PORT_NUM

Expand Down Expand Up @@ -321,7 +321,6 @@ def start_modulestore_isolation(cls):
override.__enter__() # pylint: disable=unnecessary-dunder-call
cls.__settings_overrides.append(override)
XMODULE_FACTORY_LOCK.enable()
clear_existing_modulestores()
cls.store = modulestore()

@classmethod
Expand Down Expand Up @@ -525,10 +524,6 @@ class FooTest(ModuleStoreTestCase):

The reason is: XML courses are not editable, so to reset
a course you have to reload it from disk, which is slow.

If you do need to reset an XML course, use
`clear_existing_modulestores()` directly in
your `setUp()` method.
"""

CREATE_USER = True
Expand Down
Loading