Commit 91f102c7 by Nimisha Asthagiri

Merge pull request #4232 from edx/nimisha/modulestore-enum-constants

ModulestoreEnum class.
parents d6049239 8dca8053
...@@ -3,7 +3,7 @@ Script for finding all courses whose org/name pairs == other courses when ignori ...@@ -3,7 +3,7 @@ Script for finding all courses whose org/name pairs == other courses when ignori
""" """
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore import MONGO_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
# #
...@@ -16,7 +16,7 @@ class Command(BaseCommand): ...@@ -16,7 +16,7 @@ class Command(BaseCommand):
help = 'List all courses ids in the Mongo Modulestore which may collide when ignoring case' help = 'List all courses ids in the Mongo Modulestore which may collide when ignoring case'
def handle(self, *args, **options): def handle(self, *args, **options):
mstore = modulestore()._get_modulestore_by_type(MONGO_MODULESTORE_TYPE) # pylint: disable=protected-access mstore = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo) # pylint: disable=protected-access
if hasattr(mstore, 'collection'): if hasattr(mstore, 'collection'):
map_fn = ''' map_fn = '''
function () { function () {
......
...@@ -6,7 +6,7 @@ import unittest ...@@ -6,7 +6,7 @@ import unittest
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.management import CommandError, call_command from django.core.management import CommandError, call_command
from contentstore.management.commands.migrate_to_split import Command from contentstore.management.commands.migrate_to_split import Command
from xmodule.modulestore import SPLIT_MONGO_MODULESTORE_TYPE, REVISION_OPTION_PUBLISHED_ONLY from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.modulestore.django import modulestore, clear_existing_modulestores from xmodule.modulestore.django import modulestore, clear_existing_modulestores
...@@ -56,7 +56,7 @@ class TestMigrateToSplit(ModuleStoreTestCase): ...@@ -56,7 +56,7 @@ class TestMigrateToSplit(ModuleStoreTestCase):
password = 'foo' password = 'foo'
self.user = User.objects.create_user(uname, email, password) self.user = User.objects.create_user(uname, email, password)
self.course = CourseFactory() self.course = CourseFactory()
self.addCleanup(ModuleStoreTestCase.drop_mongo_collections, SPLIT_MONGO_MODULESTORE_TYPE) self.addCleanup(ModuleStoreTestCase.drop_mongo_collections, ModuleStoreEnum.Type.split)
self.addCleanup(clear_existing_modulestores) self.addCleanup(clear_existing_modulestores)
def test_user_email(self): def test_user_email(self):
...@@ -84,6 +84,6 @@ class TestMigrateToSplit(ModuleStoreTestCase): ...@@ -84,6 +84,6 @@ class TestMigrateToSplit(ModuleStoreTestCase):
str(self.user.id), str(self.user.id),
"org.dept+name.run", "org.dept+name.run",
) )
locator = CourseLocator(org="org.dept", offering="name.run", branch=REVISION_OPTION_PUBLISHED_ONLY) locator = CourseLocator(org="org.dept", offering="name.run", branch=ModuleStoreEnum.RevisionOption.published_only)
course_from_split = modulestore('split').get_course(locator) course_from_split = modulestore('split').get_course(locator)
self.assertIsNotNone(course_from_split) self.assertIsNotNone(course_from_split)
...@@ -27,10 +27,8 @@ from xmodule.contentstore.content import StaticContent ...@@ -27,10 +27,8 @@ from xmodule.contentstore.content import StaticContent
from xmodule.contentstore.django import contentstore, _CONTENTSTORE from xmodule.contentstore.django import contentstore, _CONTENTSTORE
from xmodule.contentstore.utils import restore_asset_from_trashcan, empty_asset_trashcan from xmodule.contentstore.utils import restore_asset_from_trashcan, empty_asset_trashcan
from xmodule.exceptions import NotFoundError, InvalidVersionError from xmodule.exceptions import NotFoundError, InvalidVersionError
from xmodule.modulestore import ( from xmodule.modulestore import mongo, PublishState, ModuleStoreEnum
mongo, MONGO_MODULESTORE_TYPE, PublishState, from xmodule.modulestore.mongo.base import MongoRevisionKey
REVISION_OPTION_PUBLISHED_ONLY, REVISION_OPTION_DRAFT_ONLY, KEY_REVISION_PUBLISHED, BRANCH_PUBLISHED_ONLY
)
from xmodule.modulestore.mixed import store_branch_setting from xmodule.modulestore.mixed import store_branch_setting
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
...@@ -204,13 +202,13 @@ class ContentStoreToyCourseTest(ContentStoreTestCase): ...@@ -204,13 +202,13 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
store.convert_to_draft(html_module_from_draft_store.location, self.user.id) store.convert_to_draft(html_module_from_draft_store.location, self.user.id)
# Query get_items() and find the html item. This should just return back a single item (not 2). # Query get_items() and find the html item. This should just return back a single item (not 2).
direct_store_items = store.get_items(course_key, revision=REVISION_OPTION_PUBLISHED_ONLY) direct_store_items = store.get_items(course_key, revision=ModuleStoreEnum.RevisionOption.published_only)
html_items_from_direct_store = [item for item in direct_store_items if (item.location == html_usage_key)] html_items_from_direct_store = [item for item in direct_store_items if (item.location == html_usage_key)]
self.assertEqual(len(html_items_from_direct_store), 1) self.assertEqual(len(html_items_from_direct_store), 1)
self.assertFalse(getattr(html_items_from_direct_store[0], 'is_draft', False)) self.assertFalse(getattr(html_items_from_direct_store[0], 'is_draft', False))
# Fetch from the draft store. # Fetch from the draft store.
draft_store_items = store.get_items(course_key, revision=REVISION_OPTION_DRAFT_ONLY) draft_store_items = store.get_items(course_key, revision=ModuleStoreEnum.RevisionOption.draft_only)
html_items_from_draft_store = [item for item in draft_store_items if (item.location == html_usage_key)] html_items_from_draft_store = [item for item in draft_store_items if (item.location == html_usage_key)]
self.assertEqual(len(html_items_from_draft_store), 1) self.assertEqual(len(html_items_from_draft_store), 1)
self.assertTrue(getattr(html_items_from_draft_store[0], 'is_draft', False)) self.assertTrue(getattr(html_items_from_draft_store[0], 'is_draft', False))
...@@ -663,9 +661,9 @@ class ContentStoreToyCourseTest(ContentStoreTestCase): ...@@ -663,9 +661,9 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
clone_course(module_store, content_store, source_course_id, dest_course_id, self.user.id) clone_course(module_store, content_store, source_course_id, dest_course_id, self.user.id)
# first assert that all draft content got cloned as well # first assert that all draft content got cloned as well
draft_items = module_store.get_items(source_course_id, revision=REVISION_OPTION_DRAFT_ONLY) draft_items = module_store.get_items(source_course_id, revision=ModuleStoreEnum.RevisionOption.draft_only)
self.assertGreater(len(draft_items), 0) self.assertGreater(len(draft_items), 0)
draft_clone_items = module_store.get_items(dest_course_id, revision=REVISION_OPTION_DRAFT_ONLY) draft_clone_items = module_store.get_items(dest_course_id, revision=ModuleStoreEnum.RevisionOption.draft_only)
self.assertGreater(len(draft_clone_items), 0) self.assertGreater(len(draft_clone_items), 0)
self.assertEqual(len(draft_items), len(draft_clone_items)) self.assertEqual(len(draft_items), len(draft_clone_items))
...@@ -868,7 +866,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase): ...@@ -868,7 +866,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
# add the new private and new public to list of children # add the new private and new public to list of children
sequential = module_store.get_item(course_id.make_usage_key('sequential', 'vertical_sequential')) sequential = module_store.get_item(course_id.make_usage_key('sequential', 'vertical_sequential'))
private_location_no_draft = private_vertical.location.replace(revision=KEY_REVISION_PUBLISHED) private_location_no_draft = private_vertical.location.replace(revision=MongoRevisionKey.published)
sequential.children.append(private_location_no_draft) sequential.children.append(private_location_no_draft)
sequential.children.append(public_vertical_location) sequential.children.append(public_vertical_location)
module_store.update_item(sequential, self.user.id) module_store.update_item(sequential, self.user.id)
...@@ -939,7 +937,11 @@ class ContentStoreToyCourseTest(ContentStoreTestCase): ...@@ -939,7 +937,11 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
target_course_id=course_id, target_course_id=course_id,
) )
items = module_store.get_items(course_id, category='vertical', revision=REVISION_OPTION_PUBLISHED_ONLY) items = module_store.get_items(
course_id,
category='vertical',
revision=ModuleStoreEnum.RevisionOption.published_only
)
self._check_verticals(items) self._check_verticals(items)
def verify_item_publish_state(item, publish_state): def verify_item_publish_state(item, publish_state):
...@@ -1124,7 +1126,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase): ...@@ -1124,7 +1126,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
self.assertContains(resp, '/c4x/edX/toy/asset/handouts_sample_handout.txt') self.assertContains(resp, '/c4x/edX/toy/asset/handouts_sample_handout.txt')
def test_prefetch_children(self): def test_prefetch_children(self):
mongo_store = modulestore()._get_modulestore_by_type(MONGO_MODULESTORE_TYPE) mongo_store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo)
import_from_xml(modulestore(), self.user.id, 'common/test/data/', ['toy']) import_from_xml(modulestore(), self.user.id, 'common/test/data/', ['toy'])
course_id = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall') course_id = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
...@@ -1132,7 +1134,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase): ...@@ -1132,7 +1134,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
mongo_store.collection.find = wrapper.find mongo_store.collection.find = wrapper.find
# set the branch to 'publish' in order to prevent extra lookups of draft versions # set the branch to 'publish' in order to prevent extra lookups of draft versions
with store_branch_setting(mongo_store, BRANCH_PUBLISHED_ONLY): with store_branch_setting(mongo_store, ModuleStoreEnum.Branch.published_only):
course = mongo_store.get_course(course_id, depth=2) course = mongo_store.get_course(course_id, depth=2)
# make sure we haven't done too many round trips to DB # make sure we haven't done too many round trips to DB
......
...@@ -17,7 +17,7 @@ from student.tests.factories import UserFactory ...@@ -17,7 +17,7 @@ from student.tests.factories import UserFactory
from student.roles import CourseInstructorRole, CourseStaffRole, GlobalStaff, OrgStaffRole, OrgInstructorRole from student.roles import CourseInstructorRole, CourseStaffRole, GlobalStaff, OrgStaffRole, OrgInstructorRole
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls
from xmodule.modulestore import MONGO_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.error_module import ErrorDescriptor from xmodule.error_module import ErrorDescriptor
...@@ -199,7 +199,7 @@ class TestCourseListing(ModuleStoreTestCase): ...@@ -199,7 +199,7 @@ class TestCourseListing(ModuleStoreTestCase):
self.assertGreaterEqual(iteration_over_courses_time_2.elapsed, iteration_over_groups_time_2.elapsed) self.assertGreaterEqual(iteration_over_courses_time_2.elapsed, iteration_over_groups_time_2.elapsed)
# Now count the db queries # Now count the db queries
store = modulestore()._get_modulestore_by_type(MONGO_MODULESTORE_TYPE) store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo)
with check_mongo_calls(store.collection, USER_COURSES_COUNT): with check_mongo_calls(store.collection, USER_COURSES_COUNT):
courses_list = _accessible_courses_list_from_groups(self.request) courses_list = _accessible_courses_list_from_groups(self.request)
...@@ -262,7 +262,7 @@ class TestCourseListing(ModuleStoreTestCase): ...@@ -262,7 +262,7 @@ class TestCourseListing(ModuleStoreTestCase):
Create good courses, courses that won't load, and deleted courses which still have Create good courses, courses that won't load, and deleted courses which still have
roles. Test course listing. roles. Test course listing.
""" """
store = modulestore()._get_modulestore_by_type(MONGO_MODULESTORE_TYPE) store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo)
course_location = SlashSeparatedCourseKey('testOrg', 'testCourse', 'RunBabyRun') course_location = SlashSeparatedCourseKey('testOrg', 'testCourse', 'RunBabyRun')
self._create_course_with_access_groups(course_location, self.user) self._create_course_with_access_groups(course_location, self.user)
......
import unittest import unittest
from xmodule import templates from xmodule import templates
from xmodule.modulestore import SPLIT_MONGO_MODULESTORE_TYPE, BRANCH_NAME_DRAFT from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests import persistent_factories from xmodule.modulestore.tests import persistent_factories
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
from xmodule.modulestore.django import modulestore, clear_existing_modulestores, _MIXED_MODULESTORE, \ from xmodule.modulestore.django import modulestore, clear_existing_modulestores, _MIXED_MODULESTORE, \
...@@ -21,9 +21,9 @@ class TemplateTests(unittest.TestCase): ...@@ -21,9 +21,9 @@ class TemplateTests(unittest.TestCase):
def setUp(self): def setUp(self):
clear_existing_modulestores() # redundant w/ cleanup but someone was getting errors clear_existing_modulestores() # redundant w/ cleanup but someone was getting errors
self.addCleanup(ModuleStoreTestCase.drop_mongo_collections, SPLIT_MONGO_MODULESTORE_TYPE) self.addCleanup(ModuleStoreTestCase.drop_mongo_collections, ModuleStoreEnum.Type.split)
self.addCleanup(clear_existing_modulestores) self.addCleanup(clear_existing_modulestores)
self.split_store = modulestore()._get_modulestore_by_type(SPLIT_MONGO_MODULESTORE_TYPE) self.split_store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.split)
def test_get_templates(self): def test_get_templates(self):
found = templates.all_templates() found = templates.all_templates()
...@@ -156,7 +156,7 @@ class TemplateTests(unittest.TestCase): ...@@ -156,7 +156,7 @@ class TemplateTests(unittest.TestCase):
persistent_factories.ItemFactory.create(display_name='chapter 1', persistent_factories.ItemFactory.create(display_name='chapter 1',
parent_location=test_course.location) parent_location=test_course.location)
id_locator = test_course.id.for_branch(BRANCH_NAME_DRAFT) id_locator = test_course.id.for_branch(ModuleStoreEnum.BranchName.draft)
guid_locator = test_course.location.course_agnostic() guid_locator = test_course.location.course_agnostic()
# verify it can be retrieved by id # verify it can be retrieved by id
self.assertIsInstance(self.split_store.get_course(id_locator), CourseDescriptor) self.assertIsInstance(self.split_store.get_course(id_locator), CourseDescriptor)
...@@ -241,7 +241,7 @@ class SplitAndLocMapperTests(unittest.TestCase): ...@@ -241,7 +241,7 @@ class SplitAndLocMapperTests(unittest.TestCase):
mapper = loc_mapper() mapper = loc_mapper()
# instantiate mixed modulestore and thus split # instantiate mixed modulestore and thus split
split_store = modulestore()._get_modulestore_by_type(SPLIT_MONGO_MODULESTORE_TYPE) split_store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.split)
# split must inject the same location mapper object since the mapper existed before it did # split must inject the same location mapper object since the mapper existed before it did
self.assertEqual(split_store.loc_mapper, mapper) self.assertEqual(split_store.loc_mapper, mapper)
...@@ -254,7 +254,7 @@ class SplitAndLocMapperTests(unittest.TestCase): ...@@ -254,7 +254,7 @@ class SplitAndLocMapperTests(unittest.TestCase):
self.assertIsNone(_loc_singleton) self.assertIsNone(_loc_singleton)
# instantiate split before location mapper # instantiate split before location mapper
split_store = modulestore()._get_modulestore_by_type(SPLIT_MONGO_MODULESTORE_TYPE) split_store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.split)
# split must have instantiated loc_mapper # split must have instantiated loc_mapper
mapper = loc_mapper() mapper = loc_mapper()
......
...@@ -21,7 +21,7 @@ from xblock.fragment import Fragment ...@@ -21,7 +21,7 @@ from xblock.fragment import Fragment
import xmodule import xmodule
from xmodule.tabs import StaticTab, CourseTabList from xmodule.tabs import StaticTab, CourseTabList
from xmodule.modulestore import PublishState, REVISION_OPTION_ALL from xmodule.modulestore import PublishState, ModuleStoreEnum
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.draft import DIRECT_ONLY_CATEGORIES from xmodule.modulestore.draft import DIRECT_ONLY_CATEGORIES
from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError, DuplicateItemError from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError, DuplicateItemError
...@@ -527,7 +527,7 @@ def orphan_handler(request, course_key_string): ...@@ -527,7 +527,7 @@ def orphan_handler(request, course_key_string):
# get_orphans returns the deprecated string format w/o revision # get_orphans returns the deprecated string format w/o revision
usage_key = course_usage_key.make_usage_key_from_deprecated_string(itemloc) usage_key = course_usage_key.make_usage_key_from_deprecated_string(itemloc)
# need to delete all versions # need to delete all versions
store.delete_item(usage_key, request.user.id, revision=REVISION_OPTION_ALL) store.delete_item(usage_key, request.user.id, revision=ModuleStoreEnum.RevisionOption.all)
return JsonResponse({'deleted': items}) return JsonResponse({'deleted': items})
else: else:
raise PermissionDenied() raise PermissionDenied()
......
...@@ -247,7 +247,7 @@ XBLOCK_MIXINS = (LmsBlockMixin, InheritanceMixin, XModuleMixin) ...@@ -247,7 +247,7 @@ XBLOCK_MIXINS = (LmsBlockMixin, InheritanceMixin, XModuleMixin)
XBLOCK_SELECT_FUNCTION = prefer_xmodules XBLOCK_SELECT_FUNCTION = prefer_xmodules
############################ Modulestore Configuration ################################ ############################ Modulestore Configuration ################################
MODULESTORE_BRANCH = 'draft' MODULESTORE_BRANCH = 'draft-preferred'
############################ DJANGO_BUILTINS ################################ ############################ DJANGO_BUILTINS ################################
# Change DEBUG/TEMPLATE_DEBUG in your environment settings files, not here # Change DEBUG/TEMPLATE_DEBUG in your environment settings files, not here
......
...@@ -6,7 +6,7 @@ from staticfiles import finders ...@@ -6,7 +6,7 @@ from staticfiles import finders
from django.conf import settings from django.conf import settings
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore import XML_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.contentstore.content import StaticContent from xmodule.contentstore.content import StaticContent
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -119,7 +119,9 @@ def replace_static_urls(text, data_directory, course_id=None, static_asset_path= ...@@ -119,7 +119,9 @@ def replace_static_urls(text, data_directory, course_id=None, static_asset_path=
if settings.DEBUG and finders.find(rest, True): if settings.DEBUG and finders.find(rest, True):
return original return original
# if we're running with a MongoBacked store course_namespace is not None, then use studio style urls # if we're running with a MongoBacked store course_namespace is not None, then use studio style urls
elif (not static_asset_path) and course_id and modulestore().get_modulestore_type(course_id) != XML_MODULESTORE_TYPE: elif (not static_asset_path) \
and course_id \
and modulestore().get_modulestore_type(course_id) != ModuleStoreEnum.Type.xml:
# first look in the static file pipeline and see if we are trying to reference # first look in the static file pipeline and see if we are trying to reference
# a piece of static content which is in the edx-platform repo (e.g. JS associated with an xmodule) # a piece of static content which is in the edx-platform repo (e.g. JS associated with an xmodule)
......
...@@ -7,7 +7,7 @@ from opaque_keys import InvalidKeyError ...@@ -7,7 +7,7 @@ from opaque_keys import InvalidKeyError
import logging import logging
from django.db.models.query_utils import Q from django.db.models.query_utils import Q
from django.db.utils import IntegrityError from django.db.utils import IntegrityError
from xmodule.modulestore import XML_MODULESTORE_TYPE, MONGO_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.mixed import MixedModuleStore from xmodule.modulestore.mixed import MixedModuleStore
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -27,8 +27,8 @@ class Migration(DataMigration): ...@@ -27,8 +27,8 @@ class Migration(DataMigration):
# Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..." # Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..."
loc_map_collection = loc_mapper().location_map loc_map_collection = loc_mapper().location_map
mixed_ms = modulestore() mixed_ms = modulestore()
xml_ms = mixed_ms._get_modulestore_by_type(XML_MODULESTORE_TYPE) xml_ms = mixed_ms._get_modulestore_by_type(ModuleStoreEnum.Type.xml)
mongo_ms = mixed_ms._get_modulestore_by_type(MONGO_MODULESTORE_TYPE) mongo_ms = mixed_ms._get_modulestore_by_type(ModuleStoreEnum.Type.mongo)
query = Q(name__startswith='staff') | Q(name__startswith='instructor') | Q(name__startswith='beta_testers') query = Q(name__startswith='staff') | Q(name__startswith='instructor') | Q(name__startswith='beta_testers')
for group in orm['auth.Group'].objects.filter(query).exclude(name__contains="/").all(): for group in orm['auth.Group'].objects.filter(query).exclude(name__contains="/").all():
......
...@@ -6,7 +6,7 @@ from mock import patch, Mock ...@@ -6,7 +6,7 @@ from mock import patch, Mock
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
from student.roles import GlobalStaff from student.roles import GlobalStaff
from xmodule.modulestore import MONGO_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
...@@ -90,7 +90,7 @@ class TestCourseListing(ModuleStoreTestCase): ...@@ -90,7 +90,7 @@ class TestCourseListing(ModuleStoreTestCase):
Create good courses, courses that won't load, and deleted courses which still have Create good courses, courses that won't load, and deleted courses which still have
roles. Test course listing. roles. Test course listing.
""" """
mongo_store = modulestore()._get_modulestore_by_type(MONGO_MODULESTORE_TYPE) mongo_store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo)
good_location = SlashSeparatedCourseKey('testOrg', 'testCourse', 'RunBabyRun') good_location = SlashSeparatedCourseKey('testOrg', 'testCourse', 'RunBabyRun')
self._create_course_with_access_groups(good_location) self._create_course_with_access_groups(good_location)
......
...@@ -53,7 +53,7 @@ from dark_lang.models import DarkLangConfig ...@@ -53,7 +53,7 @@ from dark_lang.models import DarkLangConfig
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
from xmodule.modulestore import XML_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from collections import namedtuple from collections import namedtuple
...@@ -462,7 +462,7 @@ def dashboard(request): ...@@ -462,7 +462,7 @@ def dashboard(request):
show_email_settings_for = frozenset( show_email_settings_for = frozenset(
course.id for course, _enrollment in course_enrollment_pairs if ( course.id for course, _enrollment in course_enrollment_pairs if (
settings.FEATURES['ENABLE_INSTRUCTOR_EMAIL'] and settings.FEATURES['ENABLE_INSTRUCTOR_EMAIL'] and
modulestore().get_modulestore_type(course.id) != XML_MODULESTORE_TYPE and modulestore().get_modulestore_type(course.id) != ModuleStoreEnum.Type.xml and
CourseAuthorization.instructor_email_enabled(course.id) CourseAuthorization.instructor_email_enabled(course.id)
) )
) )
......
...@@ -19,7 +19,7 @@ from json import dumps ...@@ -19,7 +19,7 @@ from json import dumps
from pymongo import MongoClient from pymongo import MongoClient
import xmodule.modulestore.django import xmodule.modulestore.django
from xmodule.contentstore.django import _CONTENTSTORE from xmodule.contentstore.django import _CONTENTSTORE
from xmodule.modulestore import MONGO_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
# There is an import issue when using django-staticfiles with lettuce # There is an import issue when using django-staticfiles with lettuce
# Lettuce assumes that we are using django.contrib.staticfiles, # Lettuce assumes that we are using django.contrib.staticfiles,
...@@ -190,7 +190,7 @@ def reset_databases(scenario): ...@@ -190,7 +190,7 @@ def reset_databases(scenario):
mongo.drop_database(settings.CONTENTSTORE['DOC_STORE_CONFIG']['db']) mongo.drop_database(settings.CONTENTSTORE['DOC_STORE_CONFIG']['db'])
_CONTENTSTORE.clear() _CONTENTSTORE.clear()
modulestore = xmodule.modulestore.django.modulestore()._get_modulestore_by_type(MONGO_MODULESTORE_TYPE) modulestore = xmodule.modulestore.django.modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo)
modulestore.collection.drop() modulestore.collection.drop()
xmodule.modulestore.django.clear_existing_modulestores() xmodule.modulestore.django.clear_existing_modulestores()
......
...@@ -6,7 +6,7 @@ from lettuce import world ...@@ -6,7 +6,7 @@ from lettuce import world
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from student.models import CourseEnrollment from student.models import CourseEnrollment
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore import MONGO_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.contentstore.django import contentstore from xmodule.contentstore.django import contentstore
...@@ -72,6 +72,6 @@ def clear_courses(): ...@@ -72,6 +72,6 @@ def clear_courses():
# (though it shouldn't), do this manually # (though it shouldn't), do this manually
# from the bash shell to drop it: # from the bash shell to drop it:
# $ mongo test_xmodule --eval "db.dropDatabase()" # $ mongo test_xmodule --eval "db.dropDatabase()"
store = modulestore()._get_modulestore_by_type(MONGO_MODULESTORE_TYPE) store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo)
store.collection.drop() store.collection.drop()
contentstore().fs_files.drop() contentstore().fs_files.drop()
...@@ -16,7 +16,7 @@ from xblock.fragment import Fragment ...@@ -16,7 +16,7 @@ from xblock.fragment import Fragment
from xmodule.seq_module import SequenceModule from xmodule.seq_module import SequenceModule
from xmodule.vertical_module import VerticalModule from xmodule.vertical_module import VerticalModule
from xmodule.x_module import shim_xmodule_js, XModuleDescriptor, XModule, PREVIEW_VIEWS, STUDIO_VIEW from xmodule.x_module import shim_xmodule_js, XModuleDescriptor, XModule, PREVIEW_VIEWS, STUDIO_VIEW
from xmodule.modulestore import MONGO_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -169,7 +169,7 @@ def add_staff_markup(user, has_instructor_access, block, view, frag, context): ...@@ -169,7 +169,7 @@ def add_staff_markup(user, has_instructor_access, block, view, frag, context):
# TODO: make this more general, eg use an XModule attribute instead # TODO: make this more general, eg use an XModule attribute instead
if isinstance(block, VerticalModule) and (not context or not context.get('child_of_vertical', False)): if isinstance(block, VerticalModule) and (not context or not context.get('child_of_vertical', False)):
# check that the course is a mongo backed Studio course before doing work # check that the course is a mongo backed Studio course before doing work
is_mongo_course = modulestore().get_modulestore_type(block.location.course_key) == MONGO_MODULESTORE_TYPE is_mongo_course = modulestore().get_modulestore_type(block.location.course_key) == ModuleStoreEnum.Type.mongo
is_studio_course = block.course_edit_method == "Studio" is_studio_course = block.course_edit_method == "Studio"
if is_studio_course and is_mongo_course: if is_studio_course and is_mongo_course:
......
...@@ -25,44 +25,51 @@ from xblock.core import XBlock ...@@ -25,44 +25,51 @@ from xblock.core import XBlock
log = logging.getLogger('edx.modulestore') log = logging.getLogger('edx.modulestore')
# Modulestore Types
SPLIT_MONGO_MODULESTORE_TYPE = 'split' class ModuleStoreEnum(object):
MONGO_MODULESTORE_TYPE = 'mongo' """
XML_MODULESTORE_TYPE = 'xml' A class to encapsulate common constants that are used with the various modulestores.
"""
# Key Revision constants to use for Location and Usage Keys
# Note: These values are persisted in the database, so should not be changed without migrations
KEY_REVISION_DRAFT = 'draft'
KEY_REVISION_PUBLISHED = None
# Revision constants to use for Module Store operations
# Note: These values are passed into store APIs and only used at run time
# both DRAFT and PUBLISHED versions are queried, with preference to DRAFT versions
REVISION_OPTION_DRAFT_PREFERRED = 'rev-opt-draft-preferred'
# only DRAFT versions are queried and no PUBLISHED versions class Type(object):
REVISION_OPTION_DRAFT_ONLY = 'rev-opt-draft-only' """
The various types of modulestores provided
"""
split = 'split'
mongo = 'mongo'
xml = 'xml'
# # only PUBLISHED versions are queried and no DRAFT versions class RevisionOption(object):
REVISION_OPTION_PUBLISHED_ONLY = 'rev-opt-published-only' """
Revision constants to use for Module Store operations
Note: These values are passed into store APIs and only used at run time
"""
# both DRAFT and PUBLISHED versions are queried, with preference to DRAFT versions
draft_preferred = 'rev-opt-draft-preferred'
# all revisions are queried # only DRAFT versions are queried and no PUBLISHED versions
REVISION_OPTION_ALL = 'rev-opt-all' draft_only = 'rev-opt-draft-only'
# # only PUBLISHED versions are queried and no DRAFT versions
published_only = 'rev-opt-published-only'
# Branch constants to use for stores, such as Mongo, that have only 2 branches: DRAFT and PUBLISHED # all revisions are queried
# Note: These values are taken from server configuration settings, so should not be changed without alerting DevOps all = 'rev-opt-all'
BRANCH_DRAFT_PREFERRED = 'draft'
BRANCH_PUBLISHED_ONLY = 'published'
class Branch(object):
"""
Branch constants to use for stores, such as Mongo, that have only 2 branches: DRAFT and PUBLISHED
Note: These values are taken from server configuration settings, so should not be changed without alerting DevOps
"""
draft_preferred = 'draft-preferred'
published_only = 'published-only'
# Branch constants to use for stores, such as Split, that have named branches class BranchName(object):
BRANCH_NAME_DRAFT = 'draft' """
BRANCH_NAME_PUBLISHED = 'published' Branch constants to use for stores, such as Split, that have named branches
"""
draft = 'draft-branch'
published = 'published-branch'
class PublishState(object): class PublishState(object):
......
...@@ -7,7 +7,7 @@ import pymongo ...@@ -7,7 +7,7 @@ import pymongo
import bson.son import bson.son
import urllib import urllib
from xmodule.modulestore import BRANCH_NAME_PUBLISHED, BRANCH_NAME_DRAFT from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
...@@ -55,7 +55,9 @@ class LocMapperStore(object): ...@@ -55,7 +55,9 @@ class LocMapperStore(object):
# location_map functions # location_map functions
def create_map_entry(self, course_key, org=None, offering=None, def create_map_entry(self, course_key, org=None, offering=None,
draft_branch=BRANCH_NAME_DRAFT, prod_branch=BRANCH_NAME_PUBLISHED, block_map=None): draft_branch=ModuleStoreEnum.BranchName.draft,
prod_branch=ModuleStoreEnum.BranchName.published,
block_map=None):
""" """
Add a new entry to map this SlashSeparatedCourseKey to the new style CourseLocator.org & offering. If Add a new entry to map this SlashSeparatedCourseKey to the new style CourseLocator.org & offering. If
org and offering are not provided, it defaults them based on course_key. org and offering are not provided, it defaults them based on course_key.
...@@ -245,7 +247,7 @@ class LocMapperStore(object): ...@@ -245,7 +247,7 @@ class LocMapperStore(object):
for old_name, cat_to_usage in entry['block_map'].iteritems(): for old_name, cat_to_usage in entry['block_map'].iteritems():
for category, block_id in cat_to_usage.iteritems(): for category, block_id in cat_to_usage.iteritems():
# cache all entries and then figure out if we have the one we want # cache all entries and then figure out if we have the one we want
# Always return revision=KEY_REVISION_PUBLISHED because the # Always return revision=MongoRevisionKey.published because the
# old draft module store wraps locations as draft before # old draft module store wraps locations as draft before
# trying to access things. # trying to access things.
location = old_course_id.make_usage_key( location = old_course_id.make_usage_key(
......
...@@ -110,11 +110,7 @@ class MixedModuleStore(ModuleStoreWriteBase): ...@@ -110,11 +110,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
def _get_modulestore_by_type(self, modulestore_type): def _get_modulestore_by_type(self, modulestore_type):
""" """
This method should only really be used by tests and migration scripts when necessary. This method should only really be used by tests and migration scripts when necessary.
Returns the module store as requested by type. The type can be: Returns the module store as requested by type. The type can be a value from ModuleStoreEnum.Type.
SPLIT_MONGO_MODULESTORE_TYPE
MONGO_MODULESTORE_TYPE
XML_MODULESTORE_TYPE
""" """
for store in self.modulestores: for store in self.modulestores:
if store.get_modulestore_type() == modulestore_type: if store.get_modulestore_type() == modulestore_type:
......
...@@ -33,11 +33,7 @@ from xblock.runtime import KvsFieldData ...@@ -33,11 +33,7 @@ from xblock.runtime import KvsFieldData
from xblock.exceptions import InvalidScopeError from xblock.exceptions import InvalidScopeError
from xblock.fields import Scope, ScopeIds, Reference, ReferenceList, ReferenceValueDict from xblock.fields import Scope, ScopeIds, Reference, ReferenceList, ReferenceValueDict
from xmodule.modulestore import ( from xmodule.modulestore import ModuleStoreWriteBase, ModuleStoreEnum
ModuleStoreWriteBase, MONGO_MODULESTORE_TYPE,
REVISION_OPTION_PUBLISHED_ONLY, REVISION_OPTION_DRAFT_PREFERRED,
KEY_REVISION_DRAFT, KEY_REVISION_PUBLISHED
)
from opaque_keys.edx.locations import Location from opaque_keys.edx.locations import Location
from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError, ReferentialIntegrityError from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError, ReferentialIntegrityError
from xmodule.modulestore.inheritance import own_metadata, InheritanceMixin, inherit_metadata, InheritanceKeyValueStore from xmodule.modulestore.inheritance import own_metadata, InheritanceMixin, inherit_metadata, InheritanceKeyValueStore
...@@ -58,6 +54,15 @@ SORT_REVISION_FAVOR_DRAFT = ('_id.revision', pymongo.DESCENDING) ...@@ -58,6 +54,15 @@ SORT_REVISION_FAVOR_DRAFT = ('_id.revision', pymongo.DESCENDING)
SORT_REVISION_FAVOR_PUBLISHED = ('_id.revision', pymongo.ASCENDING) SORT_REVISION_FAVOR_PUBLISHED = ('_id.revision', pymongo.ASCENDING)
class MongoRevisionKey(object):
"""
Key Revision constants to use for Location and Usage Keys in the Mongo modulestore
Note: These values are persisted in the database, so should not be changed without migrations
"""
draft = 'draft'
published = None
class InvalidWriteError(Exception): class InvalidWriteError(Exception):
""" """
Raised to indicate that writing to a particular key Raised to indicate that writing to a particular key
...@@ -303,14 +308,14 @@ def as_draft(location): ...@@ -303,14 +308,14 @@ def as_draft(location):
""" """
if location.category in DIRECT_ONLY_CATEGORIES: if location.category in DIRECT_ONLY_CATEGORIES:
return location return location
return location.replace(revision=KEY_REVISION_DRAFT) return location.replace(revision=MongoRevisionKey.draft)
def as_published(location): def as_published(location):
""" """
Returns the Location that is the published version for `location` Returns the Location that is the published version for `location`
""" """
return location.replace(revision=KEY_REVISION_PUBLISHED) return location.replace(revision=MongoRevisionKey.published)
class MongoModuleStore(ModuleStoreWriteBase): class MongoModuleStore(ModuleStoreWriteBase):
...@@ -744,7 +749,7 @@ class MongoModuleStore(ModuleStoreWriteBase): ...@@ -744,7 +749,7 @@ class MongoModuleStore(ModuleStoreWriteBase):
for key in ('tag', 'org', 'course', 'category', 'name', 'revision') for key in ('tag', 'org', 'course', 'category', 'name', 'revision')
]) ])
def get_items(self, course_id, settings=None, content=None, key_revision=KEY_REVISION_PUBLISHED, **kwargs): def get_items(self, course_id, settings=None, content=None, key_revision=MongoRevisionKey.published, **kwargs):
""" """
Returns: Returns:
list of XModuleDescriptor instances for the matching items within the course with list of XModuleDescriptor instances for the matching items within the course with
...@@ -763,10 +768,10 @@ class MongoModuleStore(ModuleStoreWriteBase): ...@@ -763,10 +768,10 @@ class MongoModuleStore(ModuleStoreWriteBase):
content (dict): fields to look for which have content scope. Follows same syntax and content (dict): fields to look for which have content scope. Follows same syntax and
rules as kwargs below. rules as kwargs below.
key_revision (str): the revision of the items you're looking for. key_revision (str): the revision of the items you're looking for.
KEY_REVISION_DRAFT - only returns drafts MongoRevisionKey.draft - only returns drafts
KEY_REVISION_PUBLISHED (equates to None) - only returns published MongoRevisionKey.published (equates to None) - only returns published
If you want one of each matching xblock but preferring draft to published, call this same method If you want one of each matching xblock but preferring draft to published, call this same method
on the draft modulestore with REVISION_OPTION_DRAFT_PREFERRED. on the draft modulestore with ModuleStoreEnum.RevisionOption.draft_preferred.
kwargs (key=value): what to look for within the course. kwargs (key=value): what to look for within the course.
Common qualifiers are ``category`` or any field name. if the target field is a list, Common qualifiers are ``category`` or any field name. if the target field is a list,
then it searches for the given value in the list not list equivalence. then it searches for the given value in the list not list equivalence.
...@@ -1003,7 +1008,7 @@ class MongoModuleStore(ModuleStoreWriteBase): ...@@ -1003,7 +1008,7 @@ class MongoModuleStore(ModuleStoreWriteBase):
value[key] = subvalue.to_deprecated_string() value[key] = subvalue.to_deprecated_string()
return jsonfields return jsonfields
def get_parent_location(self, location, revision=REVISION_OPTION_PUBLISHED_ONLY, **kwargs): def get_parent_location(self, location, revision=ModuleStoreEnum.RevisionOption.published_only, **kwargs):
''' '''
Find the location that is the parent of this location in this course. Find the location that is the parent of this location in this course.
...@@ -1011,21 +1016,24 @@ class MongoModuleStore(ModuleStoreWriteBase): ...@@ -1011,21 +1016,24 @@ class MongoModuleStore(ModuleStoreWriteBase):
Args: Args:
revision: revision:
REVISION_OPTION_PUBLISHED_ONLY - return only the PUBLISHED parent if it exists, else returns None ModuleStoreEnum.RevisionOption.published_only
REVISION_OPTION_DRAFT_PREFERRED - return either the DRAFT or PUBLISHED parent, - return only the PUBLISHED parent if it exists, else returns None
ModuleStoreEnum.RevisionOption.draft_preferred
- return either the DRAFT or PUBLISHED parent,
preferring DRAFT, if parent(s) exists, preferring DRAFT, if parent(s) exists,
else returns None else returns None
''' '''
assert location.revision is None assert location.revision is None
assert revision == REVISION_OPTION_PUBLISHED_ONLY or revision == REVISION_OPTION_DRAFT_PREFERRED assert revision == ModuleStoreEnum.RevisionOption.published_only \
or revision == ModuleStoreEnum.RevisionOption.draft_preferred
# create a query with tag, org, course, and the children field set to the given location # create a query with tag, org, course, and the children field set to the given location
query = self._course_key_to_son(location.course_key) query = self._course_key_to_son(location.course_key)
query['definition.children'] = location.to_deprecated_string() query['definition.children'] = location.to_deprecated_string()
# if only looking for the PUBLISHED parent, set the revision in the query to None # if only looking for the PUBLISHED parent, set the revision in the query to None
if revision == REVISION_OPTION_PUBLISHED_ONLY: if revision == ModuleStoreEnum.RevisionOption.published_only:
query['_id.revision'] = KEY_REVISION_PUBLISHED query['_id.revision'] = MongoRevisionKey.published
# query the collection, sorting by DRAFT first # query the collection, sorting by DRAFT first
parents = self.collection.find(query, {'_id': True}, sort=[SORT_REVISION_FAVOR_DRAFT]) parents = self.collection.find(query, {'_id': True}, sort=[SORT_REVISION_FAVOR_DRAFT])
...@@ -1034,7 +1042,7 @@ class MongoModuleStore(ModuleStoreWriteBase): ...@@ -1034,7 +1042,7 @@ class MongoModuleStore(ModuleStoreWriteBase):
# no parents were found # no parents were found
return None return None
if revision == REVISION_OPTION_PUBLISHED_ONLY: if revision == ModuleStoreEnum.RevisionOption.published_only:
if parents.count() > 1: if parents.count() > 1:
# should never have multiple PUBLISHED parents # should never have multiple PUBLISHED parents
raise ReferentialIntegrityError( raise ReferentialIntegrityError(
...@@ -1055,16 +1063,11 @@ class MongoModuleStore(ModuleStoreWriteBase): ...@@ -1055,16 +1063,11 @@ class MongoModuleStore(ModuleStoreWriteBase):
def get_modulestore_type(self, course_key=None): def get_modulestore_type(self, course_key=None):
""" """
Returns an enumeration-like type reflecting the type of this modulestore Returns an enumeration-like type reflecting the type of this modulestore per ModuleStoreEnum.Type
The return can be one of:
"xml" (for XML based courses),
"mongo" for old-style MongoDB backed courses,
"split" for new-style split MongoDB backed courses.
Args: Args:
course_key: just for signature compatibility course_key: just for signature compatibility
""" """
return MONGO_MODULESTORE_TYPE return ModuleStoreEnum.Type.mongo
def get_orphans(self, course_key): def get_orphans(self, course_key):
""" """
...@@ -1114,6 +1117,6 @@ class MongoModuleStore(ModuleStoreWriteBase): ...@@ -1114,6 +1117,6 @@ class MongoModuleStore(ModuleStoreWriteBase):
Check that the db is reachable. Check that the db is reachable.
""" """
if self.database.connection.alive(): if self.database.connection.alive():
return {MONGO_MODULESTORE_TYPE: True} return {ModuleStoreEnum.Type.mongo: True}
else: else:
raise HeartbeatFailure("Can't connect to {}".format(self.database.name), 'mongo') raise HeartbeatFailure("Can't connect to {}".format(self.database.name), 'mongo')
...@@ -7,7 +7,7 @@ In general, it's strategy is to treat the other modulestores as read-only and to ...@@ -7,7 +7,7 @@ In general, it's strategy is to treat the other modulestores as read-only and to
manipulate storage but use existing api's. manipulate storage but use existing api's.
''' '''
from xblock.fields import Reference, ReferenceList, ReferenceValueDict from xblock.fields import Reference, ReferenceList, ReferenceValueDict
from xmodule.modulestore import BRANCH_NAME_DRAFT, BRANCH_NAME_PUBLISHED, REVISION_OPTION_DRAFT_ONLY from xmodule.modulestore import ModuleStoreEnum
class SplitMigrator(object): class SplitMigrator(object):
...@@ -85,7 +85,7 @@ class SplitMigrator(object): ...@@ -85,7 +85,7 @@ class SplitMigrator(object):
# after done w/ published items, add version for DRAFT pointing to the published structure # after done w/ published items, add version for DRAFT pointing to the published structure
index_info = self.split_modulestore.get_course_index_info(course_version_locator) index_info = self.split_modulestore.get_course_index_info(course_version_locator)
versions = index_info['versions'] versions = index_info['versions']
versions[BRANCH_NAME_DRAFT] = versions[BRANCH_NAME_PUBLISHED] versions[ModuleStoreEnum.BranchName.draft] = versions[ModuleStoreEnum.BranchName.published]
self.split_modulestore.update_course_index(index_info) self.split_modulestore.update_course_index(index_info)
# clean up orphans in published version: in old mongo, parents pointed to the union of their published and draft # clean up orphans in published version: in old mongo, parents pointed to the union of their published and draft
...@@ -98,11 +98,11 @@ class SplitMigrator(object): ...@@ -98,11 +98,11 @@ class SplitMigrator(object):
""" """
# each true update below will trigger a new version of the structure. We may want to just have one new version # each true update below will trigger a new version of the structure. We may want to just have one new version
# but that's for a later date. # but that's for a later date.
new_draft_course_loc = published_course_key.for_branch(BRANCH_NAME_DRAFT) new_draft_course_loc = published_course_key.for_branch(ModuleStoreEnum.BranchName.draft)
# to prevent race conditions of grandchilden being added before their parents and thus having no parent to # to prevent race conditions of grandchilden being added before their parents and thus having no parent to
# add to # add to
awaiting_adoption = {} awaiting_adoption = {}
for module in self.draft_modulestore.get_items(course_key, revision=REVISION_OPTION_DRAFT_ONLY): for module in self.draft_modulestore.get_items(course_key, revision=ModuleStoreEnum.RevisionOption.draft_only):
new_locator = self.loc_mapper.translate_location( new_locator = self.loc_mapper.translate_location(
module.location, False, add_entry_if_missing=True module.location, False, add_entry_if_missing=True
) )
......
...@@ -61,7 +61,7 @@ from opaque_keys.edx.locator import ( ...@@ -61,7 +61,7 @@ from opaque_keys.edx.locator import (
from xmodule.modulestore.exceptions import InsufficientSpecificationError, VersionConflictError, DuplicateItemError, \ from xmodule.modulestore.exceptions import InsufficientSpecificationError, VersionConflictError, DuplicateItemError, \
DuplicateCourseError DuplicateCourseError
from xmodule.modulestore import ( from xmodule.modulestore import (
inheritance, ModuleStoreWriteBase, SPLIT_MONGO_MODULESTORE_TYPE, BRANCH_NAME_DRAFT, BRANCH_NAME_PUBLISHED inheritance, ModuleStoreWriteBase, ModuleStoreEnum
) )
from ..exceptions import ItemNotFoundError from ..exceptions import ItemNotFoundError
...@@ -296,7 +296,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -296,7 +296,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
} }
return envelope return envelope
def get_courses(self, branch=BRANCH_NAME_DRAFT, qualifiers=None): def get_courses(self, branch=ModuleStoreEnum.BranchName.draft, qualifiers=None):
''' '''
Returns a list of course descriptors matching any given qualifiers. Returns a list of course descriptors matching any given qualifiers.
...@@ -304,9 +304,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -304,9 +304,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
legal query for mongo to use against the active_versions collection. legal query for mongo to use against the active_versions collection.
Note, this is to find the current head of the named branch type Note, this is to find the current head of the named branch type
(e.g., BRANCH_NAME_DRAFT). To get specific versions via guid use get_course. (e.g., ModuleStoreEnum.BranchName.draft). To get specific versions via guid use get_course.
:param branch: the branch for which to return courses. Default value is BRANCH_NAME_DRAFT. :param branch: the branch for which to return courses. Default value is ModuleStoreEnum.BranchName.draft.
:param qualifiers: an optional dict restricting which elements should match :param qualifiers: an optional dict restricting which elements should match
''' '''
if qualifiers is None: if qualifiers is None:
...@@ -385,9 +385,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -385,9 +385,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
:param usage_key: the block to check :param usage_key: the block to check
:return: True if the draft and published versions differ :return: True if the draft and published versions differ
""" """
draft = self.get_item(usage_key.for_branch(BRANCH_NAME_DRAFT)) draft = self.get_item(usage_key.for_branch(ModuleStoreEnum.BranchName.draft))
try: try:
published = self.get_item(usage_key.for_branch(BRANCH_NAME_PUBLISHED)) published = self.get_item(usage_key.for_branch(ModuleStoreEnum.BranchName.published))
except ItemNotFoundError: except ItemNotFoundError:
return True return True
...@@ -492,7 +492,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -492,7 +492,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
def get_orphans(self, course_key): def get_orphans(self, course_key):
""" """
Return a dict of all of the orphans in the course. Return an array of all of the orphans in the course.
""" """
detached_categories = [name for name, __ in XBlock.load_tagged_classes("detached")] detached_categories = [name for name, __ in XBlock.load_tagged_classes("detached")]
course = self._lookup_course(course_key) course = self._lookup_course(course_key)
...@@ -872,7 +872,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -872,7 +872,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
def create_course( def create_course(
self, org, offering, user_id, fields=None, self, org, offering, user_id, fields=None,
master_branch=BRANCH_NAME_DRAFT, versions_dict=None, root_category='course', master_branch=ModuleStoreEnum.BranchName.draft, versions_dict=None, root_category='course',
root_block_id='course', **kwargs root_block_id='course', **kwargs
): ):
""" """
...@@ -908,7 +908,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -908,7 +908,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
master_branch: the tag (key) for the version name in the dict which is the DRAFT version. Not the actual master_branch: the tag (key) for the version name in the dict which is the DRAFT version. Not the actual
version guid, but what to call it. version guid, but what to call it.
versions_dict: the starting version ids where the keys are the tags such as DRAFT and REVISION_OPTION_PUBLISHED_ONLY versions_dict: the starting version ids where the keys are the tags such as DRAFT and PUBLISHED
and the values are structure guids. If provided, the new course will reuse this version (unless you also and the values are structure guids. If provided, the new course will reuse this version (unless you also
provide any fields overrides, see above). if not provided, will create a mostly empty course provide any fields overrides, see above). if not provided, will create a mostly empty course
structure with just a category course root xblock. structure with just a category course root xblock.
...@@ -1298,7 +1298,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1298,7 +1298,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
self._update_head(index_entry, destination_course.branch, destination_structure['_id']) self._update_head(index_entry, destination_course.branch, destination_structure['_id'])
def unpublish(self, location, user_id): def unpublish(self, location, user_id):
published_location = location.replace(branch=REVISION_OPTION_PUBLISHED_ONLY) published_location = location.replace(branch=ModuleStoreEnum.BranchName.published)
self.delete_item(published_location, user_id) self.delete_item(published_location, user_id)
def update_course_index(self, updated_index_entry): def update_course_index(self, updated_index_entry):
...@@ -1456,16 +1456,12 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1456,16 +1456,12 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
def get_modulestore_type(self, course_key=None): def get_modulestore_type(self, course_key=None):
""" """
Returns an enumeration-like type reflecting the type of this modulestore Returns an enumeration-like type reflecting the type of this modulestore, per ModuleStoreEnum.Type.
The return can be one of:
"xml" (for XML based courses),
"mongo" for old-style MongoDB backed courses,
"split" for new-style split MongoDB backed courses.
Args: Args:
course_key: just for signature compatibility course_key: just for signature compatibility
""" """
return SPLIT_MONGO_MODULESTORE_TYPE return ModuleStoreEnum.Type.split
def internal_clean_children(self, course_locator): def internal_clean_children(self, course_locator):
""" """
...@@ -1797,7 +1793,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1797,7 +1793,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
""" """
Check that the db is reachable. Check that the db is reachable.
""" """
return {SPLIT_MONGO_MODULESTORE_TYPE: self.db_connection.heartbeat()} return {ModuleStoreEnum.Type.split: self.db_connection.heartbeat()}
def compute_publish_state(self, xblock): def compute_publish_state(self, xblock):
""" """
......
...@@ -2,7 +2,7 @@ import re ...@@ -2,7 +2,7 @@ import re
import logging import logging
from xmodule.contentstore.content import StaticContent from xmodule.contentstore.content import StaticContent
from xmodule.modulestore import REVISION_OPTION_PUBLISHED_ONLY, REVISION_OPTION_DRAFT_ONLY from xmodule.modulestore import ModuleStoreEnum
def _prefix_only_url_replace_regex(prefix): def _prefix_only_url_replace_regex(prefix):
...@@ -136,12 +136,12 @@ def clone_course(modulestore, contentstore, source_course_id, dest_course_id, us ...@@ -136,12 +136,12 @@ def clone_course(modulestore, contentstore, source_course_id, dest_course_id, us
raise Exception("Cannot find a course at {0}. Aborting".format(source_course_id)) raise Exception("Cannot find a course at {0}. Aborting".format(source_course_id))
# Get all modules under this namespace which is (tag, org, course) tuple # Get all modules under this namespace which is (tag, org, course) tuple
modules = modulestore.get_items(source_course_id, revision=REVISION_OPTION_PUBLISHED_ONLY) modules = modulestore.get_items(source_course_id, revision=ModuleStoreEnum.RevisionOption.published_only)
_clone_modules(modulestore, modules, source_course_id, dest_course_id, user_id) _clone_modules(modulestore, modules, source_course_id, dest_course_id, user_id)
course_location = dest_course_id.make_usage_key('course', dest_course_id.run) course_location = dest_course_id.make_usage_key('course', dest_course_id.run)
modulestore.publish(course_location, user_id) modulestore.publish(course_location, user_id)
modules = modulestore.get_items(source_course_id, revision=REVISION_OPTION_DRAFT_ONLY) modules = modulestore.get_items(source_course_id, revision=ModuleStoreEnum.RevisionOption.draft_only)
_clone_modules(modulestore, modules, source_course_id, dest_course_id, user_id) _clone_modules(modulestore, modules, source_course_id, dest_course_id, user_id)
# now iterate through all of the assets and clone them # now iterate through all of the assets and clone them
......
...@@ -6,7 +6,7 @@ from uuid import uuid4 ...@@ -6,7 +6,7 @@ from uuid import uuid4
from django.test import TestCase from django.test import TestCase
from xmodule.modulestore.django import ( from xmodule.modulestore.django import (
modulestore, clear_existing_modulestores, loc_mapper) modulestore, clear_existing_modulestores, loc_mapper)
from xmodule.modulestore import MONGO_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.contentstore.django import contentstore from xmodule.contentstore.django import contentstore
...@@ -142,7 +142,7 @@ class ModuleStoreTestCase(TestCase): ...@@ -142,7 +142,7 @@ class ModuleStoreTestCase(TestCase):
return updated_course return updated_course
@staticmethod @staticmethod
def drop_mongo_collections(modulestore_type=MONGO_MODULESTORE_TYPE): def drop_mongo_collections(modulestore_type=ModuleStoreEnum.Type.mongo):
""" """
If using a Mongo-backed modulestore & contentstore, drop the collections. If using a Mongo-backed modulestore & contentstore, drop the collections.
""" """
......
from xmodule.modulestore import SPLIT_MONGO_MODULESTORE_TYPE, BRANCH_NAME_DRAFT from xmodule.modulestore import ModuleStoreEnum
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
from xmodule.x_module import XModuleDescriptor from xmodule.x_module import XModuleDescriptor
import factory import factory
...@@ -15,7 +15,7 @@ class SplitFactory(factory.Factory): ...@@ -15,7 +15,7 @@ class SplitFactory(factory.Factory):
# Delayed import so that we only depend on django if the caller # Delayed import so that we only depend on django if the caller
# hasn't provided their own modulestore # hasn't provided their own modulestore
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
return modulestore()._get_modulestore_by_type(SPLIT_MONGO_MODULESTORE_TYPE) return modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.split)
class PersistentCourseFactory(SplitFactory): class PersistentCourseFactory(SplitFactory):
...@@ -25,7 +25,7 @@ class PersistentCourseFactory(SplitFactory): ...@@ -25,7 +25,7 @@ class PersistentCourseFactory(SplitFactory):
keywords: any xblock field plus (note, the below are filtered out; so, if they keywords: any xblock field plus (note, the below are filtered out; so, if they
become legitimate xblock fields, they won't be settable via this factory) become legitimate xblock fields, they won't be settable via this factory)
* org: defaults to textX * org: defaults to textX
* master_branch: (optional) defaults to BRANCH_NAME_DRAFT * master_branch: (optional) defaults to ModuleStoreEnum.BranchName.draft
* user_id: (optional) defaults to 'test_user' * user_id: (optional) defaults to 'test_user'
* display_name (xblock field): will default to 'Robot Super Course' unless provided * display_name (xblock field): will default to 'Robot Super Course' unless provided
""" """
...@@ -34,7 +34,7 @@ class PersistentCourseFactory(SplitFactory): ...@@ -34,7 +34,7 @@ class PersistentCourseFactory(SplitFactory):
# pylint: disable=W0613 # pylint: disable=W0613
@classmethod @classmethod
def _create(cls, target_class, offering='999', org='testX', user_id='test_user', def _create(cls, target_class, offering='999', org='testX', user_id='test_user',
master_branch=BRANCH_NAME_DRAFT, **kwargs): master_branch=ModuleStoreEnum.BranchName.draft, **kwargs):
modulestore = kwargs.pop('modulestore') modulestore = kwargs.pop('modulestore')
root_block_id = kwargs.pop('root_block_id', 'course') root_block_id = kwargs.pop('root_block_id', 'course')
......
...@@ -7,10 +7,7 @@ from collections import namedtuple ...@@ -7,10 +7,7 @@ from collections import namedtuple
from xmodule.tests import DATA_DIR from xmodule.tests import DATA_DIR
from opaque_keys.edx.locations import Location from opaque_keys.edx.locations import Location
from xmodule.modulestore import ( from xmodule.modulestore import ModuleStoreEnum
MONGO_MODULESTORE_TYPE, SPLIT_MONGO_MODULESTORE_TYPE, XML_MODULESTORE_TYPE,
REVISION_OPTION_DRAFT_PREFERRED, REVISION_OPTION_PUBLISHED_ONLY, BRANCH_DRAFT_PREFERRED
)
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
...@@ -247,12 +244,12 @@ class TestMixedModuleStore(LocMapperSetupSansDjango): ...@@ -247,12 +244,12 @@ class TestMixedModuleStore(LocMapperSetupSansDjango):
""" """
self.initdb(default_ms) self.initdb(default_ms)
self.assertEqual(self.store.get_modulestore_type( self.assertEqual(self.store.get_modulestore_type(
self._course_key_from_string(self.XML_COURSEID1)), XML_MODULESTORE_TYPE self._course_key_from_string(self.XML_COURSEID1)), ModuleStoreEnum.Type.xml
) )
self.assertEqual(self.store.get_modulestore_type( self.assertEqual(self.store.get_modulestore_type(
self._course_key_from_string(self.XML_COURSEID2)), XML_MODULESTORE_TYPE self._course_key_from_string(self.XML_COURSEID2)), ModuleStoreEnum.Type.xml
) )
mongo_ms_type = MONGO_MODULESTORE_TYPE if default_ms == 'draft' else SPLIT_MONGO_MODULESTORE_TYPE mongo_ms_type = ModuleStoreEnum.Type.mongo if default_ms == 'draft' else ModuleStoreEnum.Type.split
self.assertEqual(self.store.get_modulestore_type( self.assertEqual(self.store.get_modulestore_type(
self._course_key_from_string(self.MONGO_COURSEID)), mongo_ms_type self._course_key_from_string(self.MONGO_COURSEID)), mongo_ms_type
) )
...@@ -352,7 +349,7 @@ class TestMixedModuleStore(LocMapperSetupSansDjango): ...@@ -352,7 +349,7 @@ class TestMixedModuleStore(LocMapperSetupSansDjango):
Test that the xml modulestore only loaded the courses from the maps. Test that the xml modulestore only loaded the courses from the maps.
""" """
self.initdb('draft') self.initdb('draft')
xml_store = self.store._get_modulestore_by_type(XML_MODULESTORE_TYPE) xml_store = self.store._get_modulestore_by_type(ModuleStoreEnum.Type.xml)
courses = xml_store.get_courses() courses = xml_store.get_courses()
self.assertEqual(len(courses), 2) self.assertEqual(len(courses), 2)
course_ids = [course.id for course in courses] course_ids = [course.id for course in courses]
...@@ -366,7 +363,7 @@ class TestMixedModuleStore(LocMapperSetupSansDjango): ...@@ -366,7 +363,7 @@ class TestMixedModuleStore(LocMapperSetupSansDjango):
Test that the xml modulestore doesn't allow write ops. Test that the xml modulestore doesn't allow write ops.
""" """
self.initdb('draft') self.initdb('draft')
xml_store = self.store._get_modulestore_by_type(XML_MODULESTORE_TYPE) xml_store = self.store._get_modulestore_by_type(ModuleStoreEnum.Type.xml)
# the important thing is not which exception it raises but that it raises an exception # the important thing is not which exception it raises but that it raises an exception
with self.assertRaises(AttributeError): with self.assertRaises(AttributeError):
xml_store.create_course("org", "course/run", 999) xml_store.create_course("org", "course/run", 999)
...@@ -420,16 +417,16 @@ class TestMixedModuleStore(LocMapperSetupSansDjango): ...@@ -420,16 +417,16 @@ class TestMixedModuleStore(LocMapperSetupSansDjango):
self.verify_get_parent_locations_results([ self.verify_get_parent_locations_results([
(child_to_move, new_parent, None), (child_to_move, new_parent, None),
(child_to_move, new_parent, REVISION_OPTION_DRAFT_PREFERRED), (child_to_move, new_parent, ModuleStoreEnum.RevisionOption.draft_preferred),
(child_to_move, old_parent, REVISION_OPTION_PUBLISHED_ONLY), (child_to_move, old_parent, ModuleStoreEnum.RevisionOption.published_only),
]) ])
# publish the course again # publish the course again
self.store.publish(self.course.location, self.user_id) self.store.publish(self.course.location, self.user_id)
self.verify_get_parent_locations_results([ self.verify_get_parent_locations_results([
(child_to_move, new_parent, None), (child_to_move, new_parent, None),
(child_to_move, new_parent, REVISION_OPTION_DRAFT_PREFERRED), (child_to_move, new_parent, ModuleStoreEnum.RevisionOption.draft_preferred),
(child_to_move, new_parent, REVISION_OPTION_PUBLISHED_ONLY), (child_to_move, new_parent, ModuleStoreEnum.RevisionOption.published_only),
]) ])
@ddt.data('draft') @ddt.data('draft')
...@@ -451,16 +448,16 @@ class TestMixedModuleStore(LocMapperSetupSansDjango): ...@@ -451,16 +448,16 @@ class TestMixedModuleStore(LocMapperSetupSansDjango):
self.verify_get_parent_locations_results([ self.verify_get_parent_locations_results([
(child_to_delete, old_parent, None), (child_to_delete, old_parent, None),
# Note: The following could be an unexpected result, but we want to avoid an extra database call # Note: The following could be an unexpected result, but we want to avoid an extra database call
(child_to_delete, old_parent, REVISION_OPTION_DRAFT_PREFERRED), (child_to_delete, old_parent, ModuleStoreEnum.RevisionOption.draft_preferred),
(child_to_delete, old_parent, REVISION_OPTION_PUBLISHED_ONLY), (child_to_delete, old_parent, ModuleStoreEnum.RevisionOption.published_only),
]) ])
# publish the course again # publish the course again
self.store.publish(self.course.location, self.user_id) self.store.publish(self.course.location, self.user_id)
self.verify_get_parent_locations_results([ self.verify_get_parent_locations_results([
(child_to_delete, None, None), (child_to_delete, None, None),
(child_to_delete, None, REVISION_OPTION_DRAFT_PREFERRED), (child_to_delete, None, ModuleStoreEnum.RevisionOption.draft_preferred),
(child_to_delete, None, REVISION_OPTION_PUBLISHED_ONLY), (child_to_delete, None, ModuleStoreEnum.RevisionOption.published_only),
]) ])
@ddt.data('draft', 'split') @ddt.data('draft', 'split')
...@@ -529,6 +526,6 @@ def create_modulestore_instance(engine, doc_store_config, options, i18n_service= ...@@ -529,6 +526,6 @@ def create_modulestore_instance(engine, doc_store_config, options, i18n_service=
return class_( return class_(
doc_store_config=doc_store_config, doc_store_config=doc_store_config,
branch_setting_func=lambda: BRANCH_DRAFT_PREFERRED, branch_setting_func=lambda: ModuleStoreEnum.Branch.draft_preferred,
**options **options
) )
...@@ -20,7 +20,7 @@ from xblock.plugin import Plugin ...@@ -20,7 +20,7 @@ from xblock.plugin import Plugin
from xmodule.tests import DATA_DIR from xmodule.tests import DATA_DIR
from opaque_keys.edx.locations import Location from opaque_keys.edx.locations import Location
from xmodule.modulestore import MONGO_MODULESTORE_TYPE, BRANCH_DRAFT_PREFERRED from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.mongo import MongoModuleStore, MongoKeyValueStore from xmodule.modulestore.mongo import MongoModuleStore, MongoKeyValueStore
from xmodule.modulestore.draft import DraftModuleStore from xmodule.modulestore.draft import DraftModuleStore
from opaque_keys.edx.locations import SlashSeparatedCourseKey, AssetLocation from opaque_keys.edx.locations import SlashSeparatedCourseKey, AssetLocation
...@@ -103,7 +103,7 @@ class TestMongoModuleStore(unittest.TestCase): ...@@ -103,7 +103,7 @@ class TestMongoModuleStore(unittest.TestCase):
draft_store = DraftModuleStore( draft_store = DraftModuleStore(
doc_store_config, FS_ROOT, RENDER_TEMPLATE, doc_store_config, FS_ROOT, RENDER_TEMPLATE,
default_class=DEFAULT_CLASS, default_class=DEFAULT_CLASS,
branch_setting_func=lambda: BRANCH_DRAFT_PREFERRED branch_setting_func=lambda: ModuleStoreEnum.Branch.draft_preferred
) )
import_from_xml( import_from_xml(
draft_store, draft_store,
...@@ -148,7 +148,7 @@ class TestMongoModuleStore(unittest.TestCase): ...@@ -148,7 +148,7 @@ class TestMongoModuleStore(unittest.TestCase):
{'host': HOST, 'db': DB, 'collection': COLLECTION}, {'host': HOST, 'db': DB, 'collection': COLLECTION},
FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS
) )
assert_equals(store.get_modulestore_type(''), MONGO_MODULESTORE_TYPE) assert_equals(store.get_modulestore_type(''), ModuleStoreEnum.Type.mongo)
def test_get_courses(self): def test_get_courses(self):
'''Make sure the course objects loaded properly''' '''Make sure the course objects loaded properly'''
......
...@@ -5,7 +5,7 @@ Tests for split_migrator ...@@ -5,7 +5,7 @@ Tests for split_migrator
import uuid import uuid
import random import random
import mock import mock
from xmodule.modulestore import KEY_REVISION_PUBLISHED from xmodule.modulestore.mongo.base import MongoRevisionKey
from xmodule.modulestore.loc_mapper_store import LocMapperStore from xmodule.modulestore.loc_mapper_store import LocMapperStore
from xmodule.modulestore.split_migrator import SplitMigrator from xmodule.modulestore.split_migrator import SplitMigrator
from xmodule.modulestore.tests import test_location_mapper from xmodule.modulestore.tests import test_location_mapper
...@@ -178,7 +178,7 @@ class TestMigration(SplitWMongoCourseBoostrapper): ...@@ -178,7 +178,7 @@ class TestMigration(SplitWMongoCourseBoostrapper):
self.assertEqual( self.assertEqual(
presplit_dag_root.location, presplit_dag_root.location,
self.loc_mapper.translate_locator_to_location(split_dag_root.location).replace( self.loc_mapper.translate_locator_to_location(split_dag_root.location).replace(
revision=KEY_REVISION_PUBLISHED revision=MongoRevisionKey.published
) )
) )
# compare all fields but children # compare all fields but children
......
...@@ -11,7 +11,7 @@ import random ...@@ -11,7 +11,7 @@ import random
from xblock.fields import Scope from xblock.fields import Scope
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
from xmodule.modulestore import BRANCH_NAME_PUBLISHED, BRANCH_NAME_DRAFT from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.exceptions import (InsufficientSpecificationError, ItemNotFoundError, VersionConflictError, from xmodule.modulestore.exceptions import (InsufficientSpecificationError, ItemNotFoundError, VersionConflictError,
DuplicateItemError, DuplicateCourseError) DuplicateItemError, DuplicateCourseError)
from opaque_keys.edx.locator import CourseLocator, BlockUsageLocator, VersionTree, LocalId from opaque_keys.edx.locator import CourseLocator, BlockUsageLocator, VersionTree, LocalId
...@@ -22,6 +22,10 @@ from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore ...@@ -22,6 +22,10 @@ from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore
from xmodule.modulestore.tests.test_modulestore import check_has_course_method from xmodule.modulestore.tests.test_modulestore import check_has_course_method
BRANCH_NAME_DRAFT = ModuleStoreEnum.BranchName.draft
BRANCH_NAME_PUBLISHED = ModuleStoreEnum.BranchName.published
class SplitModuleTest(unittest.TestCase): class SplitModuleTest(unittest.TestCase):
''' '''
The base set of tests manually populates a db w/ courses which have The base set of tests manually populates a db w/ courses which have
......
...@@ -9,7 +9,7 @@ from opaque_keys.edx.locator import CourseLocator, BlockUsageLocator ...@@ -9,7 +9,7 @@ from opaque_keys.edx.locator import CourseLocator, BlockUsageLocator
from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore
from xmodule.modulestore.mongo import MongoModuleStore, DraftMongoModuleStore from xmodule.modulestore.mongo import MongoModuleStore, DraftMongoModuleStore
from xmodule.modulestore.mongo.draft import DIRECT_ONLY_CATEGORIES from xmodule.modulestore.mongo.draft import DIRECT_ONLY_CATEGORIES
from xmodule.modulestore import BRANCH_DRAFT_PREFERRED, BRANCH_NAME_DRAFT from xmodule.modulestore import ModuleStoreEnum
from mock import Mock from mock import Mock
...@@ -41,7 +41,7 @@ class SplitWMongoCourseBoostrapper(unittest.TestCase): ...@@ -41,7 +41,7 @@ class SplitWMongoCourseBoostrapper(unittest.TestCase):
'xblock_mixins': (InheritanceMixin,) 'xblock_mixins': (InheritanceMixin,)
} }
split_course_key = CourseLocator('test_org', 'test_course.runid', branch=BRANCH_NAME_DRAFT) split_course_key = CourseLocator('test_org', 'test_course.runid', branch=ModuleStoreEnum.BranchName.draft)
def setUp(self): def setUp(self):
self.db_config['collection'] = 'modulestore{0}'.format(uuid.uuid4().hex[:5]) self.db_config['collection'] = 'modulestore{0}'.format(uuid.uuid4().hex[:5])
...@@ -56,7 +56,7 @@ class SplitWMongoCourseBoostrapper(unittest.TestCase): ...@@ -56,7 +56,7 @@ class SplitWMongoCourseBoostrapper(unittest.TestCase):
self.addCleanup(self.tear_down_split) self.addCleanup(self.tear_down_split)
self.old_mongo = MongoModuleStore(self.db_config, **self.modulestore_options) self.old_mongo = MongoModuleStore(self.db_config, **self.modulestore_options)
self.draft_mongo = DraftMongoModuleStore( self.draft_mongo = DraftMongoModuleStore(
self.db_config, branch_setting_func=lambda: BRANCH_DRAFT_PREFERRED, **self.modulestore_options self.db_config, branch_setting_func=lambda: ModuleStoreEnum.Branch.draft_preferred, **self.modulestore_options
) )
self.addCleanup(self.tear_down_mongo) self.addCleanup(self.tear_down_mongo)
self.old_course_key = None self.old_course_key = None
......
...@@ -9,7 +9,7 @@ from mock import patch ...@@ -9,7 +9,7 @@ from mock import patch
from xmodule.modulestore.xml import XMLModuleStore from xmodule.modulestore.xml import XMLModuleStore
from opaque_keys.edx.locations import Location from opaque_keys.edx.locations import Location
from xmodule.modulestore import XML_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from .test_modulestore import check_path_to_location from .test_modulestore import check_path_to_location
from xmodule.tests import DATA_DIR from xmodule.tests import DATA_DIR
...@@ -43,7 +43,7 @@ class TestXMLModuleStore(unittest.TestCase): ...@@ -43,7 +43,7 @@ class TestXMLModuleStore(unittest.TestCase):
def test_xml_modulestore_type(self): def test_xml_modulestore_type(self):
store = XMLModuleStore(DATA_DIR, course_dirs=['toy', 'simple']) store = XMLModuleStore(DATA_DIR, course_dirs=['toy', 'simple'])
self.assertEqual(store.get_modulestore_type(), XML_MODULESTORE_TYPE) self.assertEqual(store.get_modulestore_type(), ModuleStoreEnum.Type.xml)
def test_unicode_chars_in_xml_content(self): def test_unicode_chars_in_xml_content(self):
# edX/full/6.002_Spring_2012 has non-ASCII chars, and during # edX/full/6.002_Spring_2012 has non-ASCII chars, and during
......
...@@ -19,7 +19,7 @@ from xmodule.errortracker import make_error_tracker, exc_info_to_str ...@@ -19,7 +19,7 @@ from xmodule.errortracker import make_error_tracker, exc_info_to_str
from xmodule.mako_module import MakoDescriptorSystem from xmodule.mako_module import MakoDescriptorSystem
from xmodule.x_module import XMLParsingSystem, policy_key from xmodule.x_module import XMLParsingSystem, policy_key
from xmodule.modulestore.xml_exporter import DEFAULT_CONTENT_FIELDS from xmodule.modulestore.xml_exporter import DEFAULT_CONTENT_FIELDS
from xmodule.modulestore import REVISION_OPTION_PUBLISHED_ONLY from xmodule.modulestore import ModuleStoreEnum
from xmodule.tabs import CourseTabList from xmodule.tabs import CourseTabList
from opaque_keys.edx.keys import UsageKey from opaque_keys.edx.keys import UsageKey
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
...@@ -27,7 +27,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey ...@@ -27,7 +27,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
from xblock.field_data import DictFieldData from xblock.field_data import DictFieldData
from xblock.runtime import DictKeyValueStore, IdGenerator from xblock.runtime import DictKeyValueStore, IdGenerator
from . import ModuleStoreReadBase, Location, XML_MODULESTORE_TYPE from . import ModuleStoreReadBase, Location, ModuleStoreEnum
from .exceptions import ItemNotFoundError from .exceptions import ItemNotFoundError
from .inheritance import compute_inherited_metadata, inheriting_field_data from .inheritance import compute_inherited_metadata, inheriting_field_data
...@@ -411,7 +411,7 @@ class XMLModuleStore(ModuleStoreReadBase): ...@@ -411,7 +411,7 @@ class XMLModuleStore(ModuleStoreReadBase):
self.i18n_service = i18n_service self.i18n_service = i18n_service
# The XML Module Store is a read-only store and only handles published content # The XML Module Store is a read-only store and only handles published content
self.branch_setting_func = lambda: REVISION_OPTION_PUBLISHED_ONLY self.branch_setting_func = lambda: ModuleStoreEnum.RevisionOption.published_only
# If we are specifically asked for missing courses, that should # If we are specifically asked for missing courses, that should
# be an error. If we are asked for "all" courses, find the ones # be an error. If we are asked for "all" courses, find the ones
...@@ -800,16 +800,11 @@ class XMLModuleStore(ModuleStoreReadBase): ...@@ -800,16 +800,11 @@ class XMLModuleStore(ModuleStoreReadBase):
def get_modulestore_type(self, course_key=None): def get_modulestore_type(self, course_key=None):
""" """
Returns an enumeration-like type reflecting the type of this modulestore Returns an enumeration-like type reflecting the type of this modulestore, per ModuleStoreEnum.Type
The return can be one of:
"xml" (for XML based courses),
"mongo" for old-style MongoDB backed courses,
"split" for new-style split MongoDB backed courses.
Args: Args:
course_key: just for signature compatibility course_key: just for signature compatibility
""" """
return XML_MODULESTORE_TYPE return ModuleStoreEnum.Type.xml
def get_courses_for_wiki(self, wiki_slug): def get_courses_for_wiki(self, wiki_slug):
""" """
...@@ -827,5 +822,5 @@ class XMLModuleStore(ModuleStoreReadBase): ...@@ -827,5 +822,5 @@ class XMLModuleStore(ModuleStoreReadBase):
Returns the course count Returns the course count
""" """
return {XML_MODULESTORE_TYPE: True} return {ModuleStoreEnum.Type.xml: True}
...@@ -7,9 +7,7 @@ import lxml.etree ...@@ -7,9 +7,7 @@ import lxml.etree
from xblock.fields import Scope from xblock.fields import Scope
from xmodule.contentstore.content import StaticContent from xmodule.contentstore.content import StaticContent
from xmodule.exceptions import NotFoundError from xmodule.exceptions import NotFoundError
from xmodule.modulestore import ( from xmodule.modulestore import EdxJSONEncoder, ModuleStoreEnum
EdxJSONEncoder, BRANCH_PUBLISHED_ONLY, REVISION_OPTION_DRAFT_PREFERRED, REVISION_OPTION_DRAFT_ONLY
)
from xmodule.modulestore.inheritance import own_metadata from xmodule.modulestore.inheritance import own_metadata
from xmodule.modulestore.mixed import store_branch_setting from xmodule.modulestore.mixed import store_branch_setting
from fs.osfs import OSFS from fs.osfs import OSFS
...@@ -47,7 +45,7 @@ def export_to_xml(modulestore, contentstore, course_key, root_dir, course_dir): ...@@ -47,7 +45,7 @@ def export_to_xml(modulestore, contentstore, course_key, root_dir, course_dir):
root = lxml.etree.Element('unknown') root = lxml.etree.Element('unknown')
# export only the published content # export only the published content
with store_branch_setting(course.runtime.modulestore, BRANCH_PUBLISHED_ONLY): with store_branch_setting(course.runtime.modulestore, ModuleStoreEnum.Branch.published_only):
course.add_xml_to_node(root) course.add_xml_to_node(root)
with export_fs.open('course.xml', 'w') as course_xml: with export_fs.open('course.xml', 'w') as course_xml:
...@@ -107,11 +105,18 @@ def export_to_xml(modulestore, contentstore, course_key, root_dir, course_dir): ...@@ -107,11 +105,18 @@ def export_to_xml(modulestore, contentstore, course_key, root_dir, course_dir):
# should we change the application, then this assumption will no longer be valid # should we change the application, then this assumption will no longer be valid
# NOTE: we need to explicitly implement the logic for setting the vertical's parent # NOTE: we need to explicitly implement the logic for setting the vertical's parent
# and index here since the XML modulestore cannot load draft modules # and index here since the XML modulestore cannot load draft modules
draft_verticals = modulestore.get_items(course_key, category='vertical', revision=REVISION_OPTION_DRAFT_ONLY) draft_verticals = modulestore.get_items(
course_key,
category='vertical',
revision=ModuleStoreEnum.RevisionOption.draft_only
)
if len(draft_verticals) > 0: if len(draft_verticals) > 0:
draft_course_dir = export_fs.makeopendir(DRAFT_DIR) draft_course_dir = export_fs.makeopendir(DRAFT_DIR)
for draft_vertical in draft_verticals: for draft_vertical in draft_verticals:
parent_loc = modulestore.get_parent_location(draft_vertical.location, revision=REVISION_OPTION_DRAFT_PREFERRED) parent_loc = modulestore.get_parent_location(
draft_vertical.location,
revision=ModuleStoreEnum.RevisionOption.draft_preferred
)
# Don't try to export orphaned items. # Don't try to export orphaned items.
if parent_loc is not None: if parent_loc is not None:
logging.debug('parent_loc = {0}'.format(parent_loc)) logging.debug('parent_loc = {0}'.format(parent_loc))
......
...@@ -17,7 +17,7 @@ from .store_utilities import rewrite_nonportable_content_links ...@@ -17,7 +17,7 @@ from .store_utilities import rewrite_nonportable_content_links
import xblock import xblock
from xmodule.tabs import CourseTabList from xmodule.tabs import CourseTabList
from xmodule.modulestore.exceptions import InvalidLocationError from xmodule.modulestore.exceptions import InvalidLocationError
from xmodule.modulestore import KEY_REVISION_PUBLISHED, KEY_REVISION_DRAFT from xmodule.modulestore.mongo.base import MongoRevisionKey
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -505,14 +505,14 @@ def _import_course_draft( ...@@ -505,14 +505,14 @@ def _import_course_draft(
# Update the module's location to DRAFT revision # Update the module's location to DRAFT revision
# We need to call this method (instead of updating the location directly) # We need to call this method (instead of updating the location directly)
# to ensure that pure XBlock field data is updated correctly. # to ensure that pure XBlock field data is updated correctly.
_update_module_location(module, module.location.replace(revision=KEY_REVISION_DRAFT)) _update_module_location(module, module.location.replace(revision=MongoRevisionKey.draft))
# make sure our parent has us in its list of children # make sure our parent has us in its list of children
# this is to make sure private only verticals show up # this is to make sure private only verticals show up
# in the list of children since they would have been # in the list of children since they would have been
# filtered out from the non-draft store export # filtered out from the non-draft store export
if module.location.category == 'vertical': if module.location.category == 'vertical':
non_draft_location = module.location.replace(revision=KEY_REVISION_PUBLISHED) non_draft_location = module.location.replace(revision=MongoRevisionKey.published)
sequential_url = module.xml_attributes['parent_sequential_url'] sequential_url = module.xml_attributes['parent_sequential_url']
index = int(module.xml_attributes['index_in_children_list']) index = int(module.xml_attributes['index_in_children_list'])
......
...@@ -9,7 +9,7 @@ from django.core.exceptions import ValidationError ...@@ -9,7 +9,7 @@ from django.core.exceptions import ValidationError
from bulk_email.models import CourseEmailTemplate, COURSE_EMAIL_MESSAGE_BODY_TAG, CourseAuthorization from bulk_email.models import CourseEmailTemplate, COURSE_EMAIL_MESSAGE_BODY_TAG, CourseAuthorization
from opaque_keys import InvalidKeyError from opaque_keys import InvalidKeyError
from xmodule.modulestore import XML_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
...@@ -78,7 +78,7 @@ class CourseAuthorizationAdminForm(forms.ModelForm): # pylint: disable=R0924 ...@@ -78,7 +78,7 @@ class CourseAuthorizationAdminForm(forms.ModelForm): # pylint: disable=R0924
raise forms.ValidationError(msg) raise forms.ValidationError(msg)
# Now, try and discern if it is a Studio course - HTML editor doesn't work with XML courses # Now, try and discern if it is a Studio course - HTML editor doesn't work with XML courses
is_studio_course = modulestore().get_modulestore_type(course_key) != XML_MODULESTORE_TYPE is_studio_course = modulestore().get_modulestore_type(course_key) != ModuleStoreEnum.Type.xml
if not is_studio_course: if not is_studio_course:
msg = "Course Email feature is only available for courses authored in Studio. " msg = "Course Email feature is only available for courses authored in Studio. "
msg += '"{0}" appears to be an XML backed course.'.format(course_key.to_deprecated_string()) msg += '"{0}" appears to be an XML backed course.'.format(course_key.to_deprecated_string())
......
...@@ -11,7 +11,7 @@ from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE ...@@ -11,7 +11,7 @@ from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore import XML_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from mock import patch from mock import patch
...@@ -132,7 +132,7 @@ class CourseAuthorizationXMLFormTest(ModuleStoreTestCase): ...@@ -132,7 +132,7 @@ class CourseAuthorizationXMLFormTest(ModuleStoreTestCase):
def test_xml_course_authorization(self): def test_xml_course_authorization(self):
course_id = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall') course_id = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
# Assert this is an XML course # Assert this is an XML course
self.assertEqual(modulestore().get_modulestore_type(course_id), XML_MODULESTORE_TYPE) self.assertEqual(modulestore().get_modulestore_type(course_id), ModuleStoreEnum.Type.xml)
form_data = {'course_id': course_id.to_deprecated_string(), 'email_enabled': True} form_data = {'course_id': course_id.to_deprecated_string(), 'email_enabled': True}
form = CourseAuthorizationAdminForm(data=form_data) form = CourseAuthorizationAdminForm(data=form_data)
......
...@@ -8,13 +8,13 @@ from django.http import Http404 ...@@ -8,13 +8,13 @@ from django.http import Http404
from django.conf import settings from django.conf import settings
from edxmako.shortcuts import render_to_string from edxmako.shortcuts import render_to_string
from xmodule.modulestore import XML_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.keys import CourseKey
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.contentstore.content import StaticContent from xmodule.contentstore.content import StaticContent
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
from static_replace import replace_static_urls from static_replace import replace_static_urls
from xmodule.modulestore import MONGO_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.x_module import STUDENT_VIEW from xmodule.x_module import STUDENT_VIEW
from courseware.access import has_access from courseware.access import has_access
...@@ -106,7 +106,7 @@ def get_opt_course_with_access(user, action, course_key): ...@@ -106,7 +106,7 @@ def get_opt_course_with_access(user, action, course_key):
def course_image_url(course): def course_image_url(course):
"""Try to look up the image url for the course. If it's not found, """Try to look up the image url for the course. If it's not found,
log an error and return the dead link""" log an error and return the dead link"""
if course.static_asset_path or modulestore().get_modulestore_type(course.id) == XML_MODULESTORE_TYPE: if course.static_asset_path or modulestore().get_modulestore_type(course.id) == ModuleStoreEnum.Type.xml:
# If we are a static course with the course_image attribute # If we are a static course with the course_image attribute
# set different than the default, return that path so that # set different than the default, return that path so that
# courses can use custom course image paths, otherwise just # courses can use custom course image paths, otherwise just
...@@ -369,7 +369,7 @@ def get_studio_url(course_key, page): ...@@ -369,7 +369,7 @@ def get_studio_url(course_key, page):
assert(isinstance(course_key, CourseKey)) assert(isinstance(course_key, CourseKey))
course = get_course_by_id(course_key) course = get_course_by_id(course_key)
is_studio_course = course.course_edit_method == "Studio" is_studio_course = course.course_edit_method == "Studio"
is_mongo_course = modulestore().get_modulestore_type(course_key) == MONGO_MODULESTORE_TYPE is_mongo_course = modulestore().get_modulestore_type(course_key) == ModuleStoreEnum.Type.mongo
studio_link = None studio_link = None
if is_studio_course and is_mongo_course: if is_studio_course and is_mongo_course:
studio_link = get_cms_course_link(course, page) studio_link = get_cms_course_link(course, page)
......
...@@ -7,7 +7,7 @@ import mock ...@@ -7,7 +7,7 @@ import mock
from django.test.utils import override_settings from django.test.utils import override_settings
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
import xmodule.modulestore.django as store_django import xmodule.modulestore.django as store_django
from xmodule.modulestore import BRANCH_DRAFT_PREFERRED from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.tests.xml import factories as xml from xmodule.tests.xml import factories as xml
...@@ -62,18 +62,18 @@ class ModuleStoreBranchSettingTest(ModuleStoreTestCase): ...@@ -62,18 +62,18 @@ class ModuleStoreBranchSettingTest(ModuleStoreTestCase):
mock.Mock(return_value='preview.localhost') mock.Mock(return_value='preview.localhost')
) )
@override_settings( @override_settings(
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS={r'preview\.': BRANCH_DRAFT_PREFERRED}, HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS={r'preview\.': ModuleStoreEnum.Branch.draft_preferred},
MODULESTORE_BRANCH='fake_default_branch', MODULESTORE_BRANCH='fake_default_branch',
) )
def test_default_modulestore_preview_mapping(self): def test_default_modulestore_preview_mapping(self):
self.assertEqual(store_django._get_modulestore_branch_setting(), BRANCH_DRAFT_PREFERRED) self.assertEqual(store_django._get_modulestore_branch_setting(), ModuleStoreEnum.Branch.draft_preferred)
@mock.patch( @mock.patch(
'xmodule.modulestore.django.get_current_request_hostname', 'xmodule.modulestore.django.get_current_request_hostname',
mock.Mock(return_value='localhost') mock.Mock(return_value='localhost')
) )
@override_settings( @override_settings(
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS={r'preview\.': BRANCH_DRAFT_PREFERRED}, HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS={r'preview\.': ModuleStoreEnum.Branch.draft_preferred},
MODULESTORE_BRANCH='fake_default_branch', MODULESTORE_BRANCH='fake_default_branch',
) )
def test_default_modulestore_branch_mapping(self): def test_default_modulestore_branch_mapping(self):
......
...@@ -10,7 +10,7 @@ from django.test.utils import override_settings ...@@ -10,7 +10,7 @@ from django.test.utils import override_settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.conf import settings from django.conf import settings
from xmodule.modulestore import KEY_REVISION_DRAFT from xmodule.modulestore.mongo.base import MongoRevisionKey
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.x_module import STUDENT_VIEW from xmodule.x_module import STUDENT_VIEW
...@@ -160,7 +160,7 @@ class TestLTIModuleListing(ModuleStoreTestCase): ...@@ -160,7 +160,7 @@ class TestLTIModuleListing(ModuleStoreTestCase):
parent_location=self.section2.location, parent_location=self.section2.location,
display_name="lti draft", display_name="lti draft",
category="lti", category="lti",
location=self.course.id.make_usage_key('lti', 'lti_published').replace(revision=KEY_REVISION_DRAFT), location=self.course.id.make_usage_key('lti', 'lti_published').replace(revision=MongoRevisionKey.draft),
) )
def expected_handler_url(self, handler): def expected_handler_url(self, handler):
......
...@@ -39,7 +39,7 @@ from external_auth.views import generate_password ...@@ -39,7 +39,7 @@ from external_auth.views import generate_password
from student.models import CourseEnrollment, UserProfile, Registration from student.models import CourseEnrollment, UserProfile, Registration
import track.views import track.views
from xmodule.contentstore.django import contentstore from xmodule.contentstore.django import contentstore
from xmodule.modulestore import XML_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.store_utilities import delete_course from xmodule.modulestore.store_utilities import delete_course
from xmodule.modulestore.xml import XMLModuleStore from xmodule.modulestore.xml import XMLModuleStore
...@@ -573,7 +573,7 @@ class Courses(SysadminDashboardView): ...@@ -573,7 +573,7 @@ class Courses(SysadminDashboardView):
escape(str(err)) escape(str(err))
) )
is_xml_course = (modulestore().get_modulestore_type(course_key) == XML_MODULESTORE_TYPE) is_xml_course = (modulestore().get_modulestore_type(course_key) == ModuleStoreEnum.Type.xml)
if course_found and is_xml_course: if course_found and is_xml_course:
cdir = course.data_dir cdir = course.data_dir
self.def_ms.courses.pop(cdir) self.def_ms.courses.pop(cdir)
......
...@@ -12,7 +12,7 @@ from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE ...@@ -12,7 +12,7 @@ from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
from student.tests.factories import AdminFactory from student.tests.factories import AdminFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.modulestore import XML_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from bulk_email.models import CourseAuthorization from bulk_email.models import CourseAuthorization
...@@ -103,7 +103,7 @@ class TestInstructorDashboardEmailView(ModuleStoreTestCase): ...@@ -103,7 +103,7 @@ class TestInstructorDashboardEmailView(ModuleStoreTestCase):
# in `instructor/views/legacy.py` is doing the correct thing. # in `instructor/views/legacy.py` is doing the correct thing.
with patch('xmodule.modulestore.mongo.base.MongoModuleStore.get_modulestore_type') as mock_modulestore: with patch('xmodule.modulestore.mongo.base.MongoModuleStore.get_modulestore_type') as mock_modulestore:
mock_modulestore.return_value = XML_MODULESTORE_TYPE mock_modulestore.return_value = ModuleStoreEnum.Type.xml
# Assert that the URL for the email view is not in the response # Assert that the URL for the email view is not in the response
response = self.client.get(self.url) response = self.client.get(self.url)
......
...@@ -15,7 +15,7 @@ from django.conf import settings ...@@ -15,7 +15,7 @@ from django.conf import settings
from lms.lib.xblock.runtime import quote_slashes from lms.lib.xblock.runtime import quote_slashes
from xmodule_modifiers import wrap_xblock from xmodule_modifiers import wrap_xblock
from xmodule.html_module import HtmlDescriptor from xmodule.html_module import HtmlDescriptor
from xmodule.modulestore import XML_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xblock.field_data import DictFieldData from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds from xblock.fields import ScopeIds
...@@ -37,7 +37,7 @@ def instructor_dashboard_2(request, course_id): ...@@ -37,7 +37,7 @@ def instructor_dashboard_2(request, course_id):
""" Display the instructor dashboard for a course. """ """ Display the instructor dashboard for a course. """
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
course = get_course_by_id(course_key, depth=None) course = get_course_by_id(course_key, depth=None)
is_studio_course = (modulestore().get_modulestore_type(course_key) != XML_MODULESTORE_TYPE) is_studio_course = (modulestore().get_modulestore_type(course_key) != ModuleStoreEnum.Type.xml)
access = { access = {
'admin': request.user.is_staff, 'admin': request.user.is_staff,
......
...@@ -28,7 +28,7 @@ from django.utils import timezone ...@@ -28,7 +28,7 @@ from django.utils import timezone
from xmodule_modifiers import wrap_xblock from xmodule_modifiers import wrap_xblock
import xmodule.graders as xmgraders import xmodule.graders as xmgraders
from xmodule.modulestore import XML_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
...@@ -968,7 +968,7 @@ def instructor_dashboard(request, course_id): ...@@ -968,7 +968,7 @@ def instructor_dashboard(request, course_id):
instructor_tasks = None instructor_tasks = None
# determine if this is a studio-backed course so we can provide a link to edit this course in studio # determine if this is a studio-backed course so we can provide a link to edit this course in studio
is_studio_course = modulestore().get_modulestore_type(course_key) != XML_MODULESTORE_TYPE is_studio_course = modulestore().get_modulestore_type(course_key) != ModuleStoreEnum.Type.xml
studio_url = None studio_url = None
if is_studio_course: if is_studio_course:
studio_url = get_cms_course_link(course) studio_url = get_cms_course_link(course)
......
...@@ -12,7 +12,7 @@ from django.utils.translation import ugettext as _ ...@@ -12,7 +12,7 @@ from django.utils.translation import ugettext as _
from courseware.models import StudentModule from courseware.models import StudentModule
from xmodule.fields import Date from xmodule.fields import Date
from xmodule.modulestore import XML_MODULESTORE_TYPE from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from bulk_email.models import CourseAuthorization from bulk_email.models import CourseAuthorization
...@@ -59,7 +59,7 @@ def bulk_email_is_enabled_for_course(course_id): ...@@ -59,7 +59,7 @@ def bulk_email_is_enabled_for_course(course_id):
""" """
bulk_email_enabled_globally = (settings.FEATURES['ENABLE_INSTRUCTOR_EMAIL'] == True) bulk_email_enabled_globally = (settings.FEATURES['ENABLE_INSTRUCTOR_EMAIL'] == True)
is_studio_course = (modulestore().get_modulestore_type(course_id) != XML_MODULESTORE_TYPE) is_studio_course = (modulestore().get_modulestore_type(course_id) != ModuleStoreEnum.Type.xml)
bulk_email_enabled_for_course = CourseAuthorization.instructor_email_enabled(course_id) bulk_email_enabled_for_course = CourseAuthorization.instructor_email_enabled(course_id)
if bulk_email_enabled_globally and is_studio_course and bulk_email_enabled_for_course: if bulk_email_enabled_globally and is_studio_course and bulk_email_enabled_for_course:
......
...@@ -44,5 +44,5 @@ DEBUG_TOOLBAR_PANELS += ( ...@@ -44,5 +44,5 @@ DEBUG_TOOLBAR_PANELS += (
# what the 'default' modulestore to use while processing the request # what the 'default' modulestore to use while processing the request
# for example 'preview.edx.org' should use the draft modulestore # for example 'preview.edx.org' should use the draft modulestore
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS = { HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS = {
'preview\.': 'draft' 'preview\.': 'draft-preferred'
} }
...@@ -475,7 +475,7 @@ XBLOCK_SELECT_FUNCTION = prefer_xmodules ...@@ -475,7 +475,7 @@ XBLOCK_SELECT_FUNCTION = prefer_xmodules
############# ModuleStore Configuration ########## ############# ModuleStore Configuration ##########
MODULESTORE_BRANCH = 'published' MODULESTORE_BRANCH = 'published-only'
CONTENTSTORE = None CONTENTSTORE = None
DOC_STORE_CONFIG = { DOC_STORE_CONFIG = {
'host': 'localhost', 'host': 'localhost',
......
...@@ -109,7 +109,7 @@ STATICFILES_DIRS += [ ...@@ -109,7 +109,7 @@ STATICFILES_DIRS += [
if os.path.isdir(COMMON_TEST_DATA_ROOT / course_dir) if os.path.isdir(COMMON_TEST_DATA_ROOT / course_dir)
] ]
MODULESTORE_BRANCH = 'draft' MODULESTORE_BRANCH = 'draft-preferred'
update_module_store_settings( update_module_store_settings(
MODULESTORE, MODULESTORE,
module_store_options={ module_store_options={
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment