Skip to content

Commit

Permalink
feat: hacks
Browse files Browse the repository at this point in the history
  • Loading branch information
raozixuan committed Oct 9, 2021
1 parent 5f0f770 commit 2e86019
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 19 deletions.
2 changes: 1 addition & 1 deletion onto/attrs/attribute_new.py
Expand Up @@ -295,7 +295,7 @@ def _graphql_field_constructor(self):
field_base = graphql.GraphQLField

def resolve_info(obj, context):
value = getattr(obj, self.properties.name)
value = getattr(obj, self.properties.name, None)
if isinstance(value, enum.Enum):
value = value.value
return value
Expand Down
24 changes: 23 additions & 1 deletion onto/attrs/unit.py
Expand Up @@ -855,6 +855,28 @@ def _marshmallow_field_cls(self):
return fields.DocIdField



class NodeId(DecoratorBase):
"""
For GraphQL ID
"""

@property
def _graphql_object_type(self):
import graphql
yield graphql.GraphQLNonNull(graphql.GraphQLID)
yield from self.decorated._graphql_object_type

@property
def _graphql_field_kwargs(self):
yield from self.decorated._graphql_field_kwargs
yield 'type_', self.graphql_object_type

@classmethod
def easy(cls, *args, **kwargs):
return cls.easy_property(*args, **kwargs)


class DataKey(DecoratorBase):

@property
Expand Down Expand Up @@ -932,7 +954,7 @@ def _graphql_object_type(self):
from onto.models.meta import ModelRegistry
type_cls = ModelRegistry.get_cls_from_name(obj_type_str=type_cls)
# from onto.models.utils import _graphql_object_type_from_attributed_class
yield type_cls.get_graphql_object_type()
yield type_cls.get_graphql_object_type(is_input=self.is_input)
yield from self.decorated._graphql_object_type

# @property
Expand Down
19 changes: 19 additions & 0 deletions onto/database/mock.py
Expand Up @@ -18,6 +18,16 @@ def is_document(self):

class MockDatabase(Database):

class Comparators(Database.Comparators):

eq = lambda a, b: a == b
gt = lambda a, b: a > b
ge = lambda a, b: a >= b
lt = lambda a, b: a < b
le = lambda a, b: a <= b
contains = lambda a, b: a.has(b) # TODO; check
_in = lambda a, b: a in b

@classmethod
def listener(cls):
return MockListener
Expand Down Expand Up @@ -48,6 +58,14 @@ def delete(cls, ref: Reference, transaction=_NA):
"""
del cls.d[str(ref)]

@classmethod
def query(cls, q):
qualifier = q._to_qualifier()
for k, v in cls.d.items():
if qualifier(v):
yield k, v
yield from ()


class MockListener(Listener):
from asyncio.queues import Queue
Expand Down Expand Up @@ -77,3 +95,4 @@ async def listen(cls, col, source):
async for ref, snapshot in cls._sub(col):
await source._invoke_mediator(
func_name='on_create', ref=ref, snapshot=snapshot)

30 changes: 17 additions & 13 deletions onto/mapper/fields.py
Expand Up @@ -162,23 +162,27 @@ def serialize(obj):
else:
return res

# def deserialize(value):
# """ deserialize: A callable from which to retrieve the value.
# The function must take a single argument ``value`` which is the value
# to be deserialized. It can also optionally take a ``context`` argument,
# which is a dictionary of context variables passed to the deserializer.
# If no callable is provided then ```value``` will be passed through
# unchanged.
#
# :param value:
# :return:
# """
# return value[self.data_key]
def deserialize(value):
""" deserialize: A callable from which to retrieve the value.
The function must take a single argument ``value`` which is the value
to be deserialized. It can also optionally take a ``context`` argument,
which is a dictionary of context variables passed to the deserializer.
If no callable is provided then ```value``` will be passed through
unchanged.
:param value:
:return:
"""
data_key = self.data_key
if data_key not in value:
return fields.missing_
else:
return value[data_key]

super().__init__(
*args,
serialize=serialize,
deserialize=None,
deserialize=deserialize,
**kwargs
)

Expand Down
2 changes: 1 addition & 1 deletion onto/models/utils.py
Expand Up @@ -139,7 +139,7 @@ def _graphql_field_from_attr(attr, input=False):
from onto import attrs
if attr.__class__ is attrs.attribute.EmbeddedAttribute:
e_cls = attr.type_cls
e_graphql = e_cls.get_graphql_object_type()
e_graphql = e_cls.get_graphql_object_type(is_input=input)
field = field_base(
type_=f(e_graphql),
description=attr.doc
Expand Down
16 changes: 16 additions & 0 deletions onto/query/query.py
Expand Up @@ -160,6 +160,22 @@ def make_copy(self, arguments):
return self.__class__(
ref=self.ref, parent=self.parent, arguments=arguments)

def _to_qualifier(self):
""" Returns a greedy qualifier. Performance aside, it should work.
"""
condition = self.parent.get_obj_type_condition()
arguments = [ condition, *self.arguments ]
def qualifier(snapshot):
for (key, comparator, val) in arguments:
if key not in snapshot:
continue
a = snapshot[key]
if not comparator(a, val):
return False
return True
return qualifier


def _to_firestore_query(self):
""" Returns a query with parent=cls._get_collection(), and
limits to obj_type of subclass of cls.
Expand Down
4 changes: 2 additions & 2 deletions onto/sink/graphql.py
Expand Up @@ -148,7 +148,7 @@ def _as_graphql_schema(self):
_graphql_object_type_from_attributed_class
attributed = self.view_model_cls

ot = attributed.get_graphql_object_type()
ot = attributed.get_graphql_object_type(is_input=False)

if self.many:
ot = graphql.GraphQLList(type_=ot)
Expand Down Expand Up @@ -226,7 +226,7 @@ def _register_op(self):
from gql import mutate

async def f(parent, info, **kwargs):
res = self._invoke_mediator(func_name='mutate', **kwargs)
res = await self._invoke_mediator(func_name='mutate', **kwargs)
return res

name = self.sink_name
Expand Down
2 changes: 2 additions & 0 deletions onto/source/mock.py
Expand Up @@ -32,3 +32,5 @@ def _register(self, loop: asyncio.BaseEventLoop):
_awaitable = self.dm_cls._datastore().listener().listen(col=self.dm_cls._get_collection_name(), source=self)
_ = loop.create_task(_awaitable)

def get_all(self):
return self.dm_cls._datastore().listener().get_all(col=self.dm_cls._get_collection_name())
2 changes: 1 addition & 1 deletion onto/utils.py
Expand Up @@ -73,7 +73,7 @@ def snapshot_to_obj(
# if not snapshot.exists:
# return None

d = snapshot.to_dict()
d = snapshot.to_dict() if not isinstance(snapshot, dict) else snapshot # TODO: improve
obj_cls = super_cls

if "obj_type" in d:
Expand Down

0 comments on commit 2e86019

Please sign in to comment.