[V3 Config] Update Mongo document organization to bypass doc size restriction (#2536)

* modify config to use identifier data class and update json driver

* move identifier data attributes into read only properties

* Update mongo get and set methods

* Update get/set to use UUID separately, make clear work

* Remove not implemented and fix get_raw

* Update remaining untouched get/set/clear

* Fix get_raw

* Finally fix get_raw and set_raw

* style

* This is better

* Sorry guys

* Update get behavior to handle "all" calls as expected

* style again

* Why do you do this to me

* style once more

* Update mongo schema
This commit is contained in:
Will
2019-04-03 09:04:47 -04:00
committed by GitHub
parent d6d6d14977
commit 1cd7e41f33
6 changed files with 194 additions and 77 deletions

View File

@@ -6,7 +6,7 @@ from typing import Any, Union, Tuple, Dict, Awaitable, AsyncContextManager, Type
import discord
from .data_manager import cog_data_path, core_data_path
from .drivers import get_driver
from .drivers import get_driver, IdentifierData
if TYPE_CHECKING:
from .drivers.red_base import BaseDriver
@@ -72,14 +72,14 @@ class Value:
"""
def __init__(self, identifiers: Tuple[str], default_value, driver):
self.identifiers = identifiers
def __init__(self, identifier_data: IdentifierData, default_value, driver):
self.identifier_data = identifier_data
self.default = default_value
self.driver = driver
async def _get(self, default=...):
try:
ret = await self.driver.get(*self.identifiers)
ret = await self.driver.get(self.identifier_data)
except KeyError:
return default if default is not ... else self.default
return ret
@@ -150,13 +150,13 @@ class Value:
"""
if isinstance(value, dict):
value = _str_key_dict(value)
await self.driver.set(*self.identifiers, value=value)
await self.driver.set(self.identifier_data, value=value)
async def clear(self):
"""
Clears the value from record for the data element pointed to by `identifiers`.
"""
await self.driver.clear(*self.identifiers)
await self.driver.clear(self.identifier_data)
class Group(Value):
@@ -178,13 +178,17 @@ class Group(Value):
"""
def __init__(
self, identifiers: Tuple[str], defaults: dict, driver, force_registration: bool = False
self,
identifier_data: IdentifierData,
defaults: dict,
driver,
force_registration: bool = False,
):
self._defaults = defaults
self.force_registration = force_registration
self.driver = driver
super().__init__(identifiers, {}, self.driver)
super().__init__(identifier_data, {}, self.driver)
@property
def defaults(self):
@@ -225,22 +229,24 @@ class Group(Value):
"""
is_group = self.is_group(item)
is_value = not is_group and self.is_value(item)
new_identifiers = self.identifiers + (item,)
new_identifiers = self.identifier_data.add_identifier(item)
if is_group:
return Group(
identifiers=new_identifiers,
identifier_data=new_identifiers,
defaults=self._defaults[item],
driver=self.driver,
force_registration=self.force_registration,
)
elif is_value:
return Value(
identifiers=new_identifiers, default_value=self._defaults[item], driver=self.driver
identifier_data=new_identifiers,
default_value=self._defaults[item],
driver=self.driver,
)
elif self.force_registration:
raise AttributeError("'{}' is not a valid registered Group or value.".format(item))
else:
return Value(identifiers=new_identifiers, default_value=None, driver=self.driver)
return Value(identifier_data=new_identifiers, default_value=None, driver=self.driver)
async def clear_raw(self, *nested_path: Any):
"""
@@ -262,8 +268,9 @@ class Group(Value):
Multiple arguments that mirror the arguments passed in for nested
dict access. These are casted to `str` for you.
"""
path = [str(p) for p in nested_path]
await self.driver.clear(*self.identifiers, *path)
path = tuple(str(p) for p in nested_path)
identifier_data = self.identifier_data.add_identifier(*path)
await self.driver.clear(identifier_data)
def is_group(self, item: Any) -> bool:
"""A helper method for `__getattr__`. Most developers will have no need
@@ -368,7 +375,7 @@ class Group(Value):
If the value does not exist yet in Config's internal storage.
"""
path = [str(p) for p in nested_path]
path = tuple(str(p) for p in nested_path)
if default is ...:
poss_default = self.defaults
@@ -380,8 +387,9 @@ class Group(Value):
else:
default = poss_default
identifier_data = self.identifier_data.add_identifier(*path)
try:
raw = await self.driver.get(*self.identifiers, *path)
raw = await self.driver.get(identifier_data)
except KeyError:
if default is not ...:
return default
@@ -456,10 +464,11 @@ class Group(Value):
value
The value to store.
"""
path = [str(p) for p in nested_path]
path = tuple(str(p) for p in nested_path)
identifier_data = self.identifier_data.add_identifier(*path)
if isinstance(value, dict):
value = _str_key_dict(value)
await self.driver.set(*self.identifiers, *path, value=value)
await self.driver.set(identifier_data, value=value)
class Config:
@@ -779,11 +788,17 @@ class Config:
"""
self._register_default(group_identifier, **kwargs)
def _get_base_group(self, key: str, *identifiers: str) -> Group:
def _get_base_group(self, category: str, *primary_keys: str) -> Group:
# noinspection PyTypeChecker
identifier_data = IdentifierData(
uuid=self.unique_identifier,
category=category,
primary_key=primary_keys,
identifiers=(),
)
return Group(
identifiers=(key, *identifiers),
defaults=self.defaults.get(key, {}),
identifier_data=identifier_data,
defaults=self.defaults.get(category, {}),
driver=self.driver,
force_registration=self.force_registration,
)
@@ -904,7 +919,7 @@ class Config:
ret = {}
try:
dict_ = await self.driver.get(*group.identifiers)
dict_ = await self.driver.get(group.identifier_data)
except KeyError:
pass
else:
@@ -1021,7 +1036,7 @@ class Config:
if guild is None:
group = self._get_base_group(self.MEMBER)
try:
dict_ = await self.driver.get(*group.identifiers)
dict_ = await self.driver.get(group.identifier_data)
except KeyError:
pass
else:
@@ -1030,7 +1045,7 @@ class Config:
else:
group = self._get_base_group(self.MEMBER, str(guild.id))
try:
guild_data = await self.driver.get(*group.identifiers)
guild_data = await self.driver.get(group.identifier_data)
except KeyError:
pass
else:
@@ -1057,7 +1072,8 @@ class Config:
"""
if not scopes:
# noinspection PyTypeChecker
group = Group(identifiers=(), defaults={}, driver=self.driver)
identifier_data = IdentifierData(self.unique_identifier, "", (), ())
group = Group(identifier_data, defaults={}, driver=self.driver)
else:
group = self._get_base_group(*scopes)
await group.clear()