Improved query & filtering
This commit is contained in:
parent
7a836a7f59
commit
ce85bb332a
@ -1,6 +1,9 @@
|
|||||||
import functools
|
import functools
|
||||||
from abc import ABC
|
from abc import ABC
|
||||||
from inspect import signature, Parameter
|
from inspect import signature, Parameter
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from cpl_query.extension import List
|
||||||
|
|
||||||
|
|
||||||
class FilterABC(ABC):
|
class FilterABC(ABC):
|
||||||
@ -8,33 +11,41 @@ class FilterABC(ABC):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
ABC.__init__(self)
|
ABC.__init__(self)
|
||||||
|
|
||||||
self._page_index = 0
|
self._page_index = None
|
||||||
self._page_size = 10
|
self._page_size = None
|
||||||
self._sort_direction = ''
|
self._sort_direction = None
|
||||||
self._sort_column = ''
|
self._sort_column = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def page_index(self) -> int:
|
def page_index(self) -> Optional[int]:
|
||||||
return self._page_index
|
return self._page_index
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def page_size(self) -> int:
|
def page_size(self) -> Optional[int]:
|
||||||
return self._page_size
|
return self._page_size
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sort_direction(self) -> str:
|
def sort_direction(self) -> Optional[str]:
|
||||||
return self._sort_direction
|
return self._sort_direction
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sort_column(self) -> str:
|
def sort_column(self) -> Optional[str]:
|
||||||
return self._sort_column
|
return self._sort_column
|
||||||
|
|
||||||
|
def skip_and_take(self, query: List):
|
||||||
|
if self._page_size is not None and self.page_index is not None:
|
||||||
|
skip = self.page_size * self.page_index
|
||||||
|
result = query.skip(skip).take(self.page_size)
|
||||||
|
return result
|
||||||
|
|
||||||
|
return query
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_filter(f, values: dict):
|
def get_filter(f, values: dict):
|
||||||
sig = signature(f)
|
sig = signature(f)
|
||||||
for param in sig.parameters.items():
|
for param in sig.parameters.items():
|
||||||
parameter = param[1]
|
parameter = param[1]
|
||||||
if parameter.name == 'self' or parameter.annotation == Parameter.empty:
|
if parameter.name == 'self' or parameter.name == 'cls' or parameter.annotation == Parameter.empty:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if issubclass(parameter.annotation, FilterABC):
|
if issubclass(parameter.annotation, FilterABC):
|
||||||
@ -45,7 +56,7 @@ class FilterABC(ABC):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def resolve_filter_annotation(cls, f=None):
|
def resolve_filter_annotation(cls, f=None):
|
||||||
if f is None:
|
if f is None:
|
||||||
return functools.partial(cls.filter)
|
return functools.partial(cls.resolve_filter_annotation)
|
||||||
|
|
||||||
@functools.wraps(f)
|
@functools.wraps(f)
|
||||||
def decorator(*args, **kwargs):
|
def decorator(*args, **kwargs):
|
||||||
|
37
kdb-bot/src/bot_graphql/filter/level_filter.py
Normal file
37
kdb-bot/src/bot_graphql/filter/level_filter.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
from cpl_core.dependency_injection import ServiceProviderABC
|
||||||
|
from cpl_discord.container import Guild
|
||||||
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
|
from cpl_query.extension import List
|
||||||
|
|
||||||
|
from bot_data.model.level import Level
|
||||||
|
from bot_data.model.server import Server
|
||||||
|
from bot_graphql.abc.filter_abc import FilterABC
|
||||||
|
|
||||||
|
|
||||||
|
class LevelFilter(FilterABC):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
FilterABC.__init__(self)
|
||||||
|
|
||||||
|
self._id = None
|
||||||
|
self._name = None
|
||||||
|
# self._server_id = None
|
||||||
|
|
||||||
|
def from_dict(self, values: dict):
|
||||||
|
if 'id' in values:
|
||||||
|
self._id = values['id']
|
||||||
|
|
||||||
|
def filter(self, query: List[Level]) -> List[Level]:
|
||||||
|
if self._id is not None:
|
||||||
|
query = query.where(lambda x: x.id == self._id)
|
||||||
|
|
||||||
|
if self._name is not None:
|
||||||
|
query = query.where(lambda x: self._name.lower() == x.name.lower() or self._name.lower() in x.name.lower())
|
||||||
|
|
||||||
|
# if self._server_id is not None:
|
||||||
|
# query = query.where(lambda x: x.server.server_id == self._server_id)
|
||||||
|
|
||||||
|
skip = self.page_size * self.page_index
|
||||||
|
result = query.skip(skip).take(self.page_size)
|
||||||
|
|
||||||
|
return result
|
@ -18,12 +18,10 @@ class ServerFilter(FilterABC):
|
|||||||
|
|
||||||
def from_dict(self, values: dict):
|
def from_dict(self, values: dict):
|
||||||
if 'id' in values:
|
if 'id' in values:
|
||||||
self._id = values['id']
|
self._id = int(values['id'])
|
||||||
|
|
||||||
@ServiceProviderABC.inject
|
@ServiceProviderABC.inject
|
||||||
def filter(self, query: List[Server], bot: DiscordBotServiceABC) -> List[Server]:
|
def filter(self, query: List[Server], bot: DiscordBotServiceABC) -> List[Server]:
|
||||||
result = List(Server)
|
|
||||||
|
|
||||||
if self._id is not None:
|
if self._id is not None:
|
||||||
query = query.where(lambda x: x.server_id == self._id)
|
query = query.where(lambda x: x.server_id == self._id)
|
||||||
|
|
||||||
@ -37,7 +35,4 @@ class ServerFilter(FilterABC):
|
|||||||
|
|
||||||
query = query.where(where_guild)
|
query = query.where(where_guild)
|
||||||
|
|
||||||
skip = self.page_size * self.page_index
|
return self.skip_and_take(query)
|
||||||
result = query.skip(skip).take(self.page_size)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
@ -8,6 +8,7 @@ from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
|||||||
from bot_data.service.seeder_service import SeederService
|
from bot_data.service.seeder_service import SeederService
|
||||||
from bot_graphql.abc.query_abc import QueryABC
|
from bot_graphql.abc.query_abc import QueryABC
|
||||||
from bot_graphql.graphql_service import GraphQLService
|
from bot_graphql.graphql_service import GraphQLService
|
||||||
|
from bot_graphql.queries.level_query import LevelQuery
|
||||||
from bot_graphql.queries.server_query import ServerQuery
|
from bot_graphql.queries.server_query import ServerQuery
|
||||||
from bot_graphql.query import Query
|
from bot_graphql.query import Query
|
||||||
from bot_graphql.schema import Schema
|
from bot_graphql.schema import Schema
|
||||||
@ -27,5 +28,6 @@ class GraphQLModule(ModuleABC):
|
|||||||
services.add_singleton(GraphQLService)
|
services.add_singleton(GraphQLService)
|
||||||
services.add_singleton(Query)
|
services.add_singleton(Query)
|
||||||
services.add_transient(QueryABC, ServerQuery)
|
services.add_transient(QueryABC, ServerQuery)
|
||||||
|
services.add_transient(QueryABC, LevelQuery)
|
||||||
|
|
||||||
services.add_transient(SeederService)
|
services.add_transient(SeederService)
|
||||||
|
@ -10,7 +10,7 @@ interface TableQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input ServerFilter {
|
input ServerFilter {
|
||||||
id: Int
|
id: ID
|
||||||
discord_id: String
|
discord_id: String
|
||||||
name: String
|
name: String
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ type Server implements TableQuery {
|
|||||||
name: String
|
name: String
|
||||||
clients: [Client]
|
clients: [Client]
|
||||||
members: [User]
|
members: [User]
|
||||||
level: [Level]
|
levels: [Level]
|
||||||
|
|
||||||
created_at: String
|
created_at: String
|
||||||
modified_at: String
|
modified_at: String
|
||||||
@ -86,6 +86,11 @@ type UserJoinedVoiceChannel implements TableQuery {
|
|||||||
modified_at: String
|
modified_at: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input LevelFilter {
|
||||||
|
id: ID
|
||||||
|
name: String
|
||||||
|
}
|
||||||
|
|
||||||
type Level implements TableQuery {
|
type Level implements TableQuery {
|
||||||
id: ID
|
id: ID
|
||||||
name: String
|
name: String
|
||||||
|
39
kdb-bot/src/bot_graphql/queries/level_query.py
Normal file
39
kdb-bot/src/bot_graphql/queries/level_query.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
from bot_data.model.level import Level
|
||||||
|
from bot_graphql.abc.data_query_abc import DataQueryABC
|
||||||
|
|
||||||
|
|
||||||
|
class LevelQuery(DataQueryABC):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
DataQueryABC.__init__(self, 'Level')
|
||||||
|
|
||||||
|
self.set_field('id', self.resolve_id)
|
||||||
|
self.set_field('name', self.resolve_name)
|
||||||
|
self.set_field('color', self.resolve_color)
|
||||||
|
self.set_field('min_xp', self.resolve_min_xp)
|
||||||
|
self.set_field('permissions', self.resolve_permissions)
|
||||||
|
self.set_field('server', self.resolve_server)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_id(level: Level, *_):
|
||||||
|
return level.id
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_name(level: Level, *_):
|
||||||
|
return level.name
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_color(level: Level, *_):
|
||||||
|
return level.color
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_min_xp(level: Level, *_):
|
||||||
|
return level.min_xp
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_permissions(level: Level, *_):
|
||||||
|
return level.permissions
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_server(level: Level, *_):
|
||||||
|
return level.server
|
@ -1,22 +1,28 @@
|
|||||||
from cpl_discord.service import DiscordBotServiceABC
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
|
|
||||||
|
from bot_data.abc.level_repository_abc import LevelRepositoryABC
|
||||||
from bot_data.model.server import Server
|
from bot_data.model.server import Server
|
||||||
from bot_graphql.abc.data_query_abc import DataQueryABC
|
from bot_graphql.abc.data_query_abc import DataQueryABC
|
||||||
|
from bot_graphql.abc.filter_abc import FilterABC
|
||||||
|
from bot_graphql.filter.level_filter import LevelFilter
|
||||||
|
|
||||||
|
|
||||||
class ServerQuery(DataQueryABC):
|
class ServerQuery(DataQueryABC):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
bot: DiscordBotServiceABC
|
bot: DiscordBotServiceABC,
|
||||||
|
levels: LevelRepositoryABC,
|
||||||
):
|
):
|
||||||
DataQueryABC.__init__(self, 'Server')
|
DataQueryABC.__init__(self, 'Server')
|
||||||
|
|
||||||
self._bot = bot
|
self._bot = bot
|
||||||
|
self._levels = levels
|
||||||
|
|
||||||
self.set_field('id', self.resolve_id)
|
self.set_field('id', self.resolve_id)
|
||||||
self.set_field('discord_id', self.resolve_discord_id)
|
self.set_field('discord_id', self.resolve_discord_id)
|
||||||
self.set_field('name', self.resolve_name)
|
self.set_field('name', self.resolve_name)
|
||||||
|
self.set_field('levels', self.resolve_levels)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def resolve_id(server: Server, *_):
|
def resolve_id(server: Server, *_):
|
||||||
@ -29,3 +35,10 @@ class ServerQuery(DataQueryABC):
|
|||||||
def resolve_name(self, server: Server, *_):
|
def resolve_name(self, server: Server, *_):
|
||||||
guild = self._bot.get_guild(server.discord_server_id)
|
guild = self._bot.get_guild(server.discord_server_id)
|
||||||
return None if guild is None else guild.name
|
return None if guild is None else guild.name
|
||||||
|
|
||||||
|
@FilterABC.resolve_filter_annotation
|
||||||
|
def resolve_levels(self, server: Server, *_, filter: LevelFilter = None):
|
||||||
|
if filter is not None:
|
||||||
|
return filter.filter(self._levels.get_levels_by_server_id(server.server_id))
|
||||||
|
|
||||||
|
return self._levels.get_levels_by_server_id(server.server_id)
|
||||||
|
Loading…
Reference in New Issue
Block a user