mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-21 10:17:59 -05:00
[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:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user