예제 #1
0
파일: writer.py 프로젝트: yew1eb/edgedb
def write_meta_delete_object(
    cmd: sd.DeleteObject,  # type: ignore
    *,
    classlayout: Dict[Type[so.Object], sr_struct.SchemaTypeLayout],
    schema: s_schema.Schema,
    context: sd.CommandContext,
    blocks: List[Tuple[str, Dict[str, Any]]],
    is_internal_reflection: bool,
    stdmode: bool,
) -> None:
    _descend(
        cmd,
        classlayout=classlayout,
        schema=schema,
        context=context,
        blocks=blocks,
        prerequisites=True,
        is_internal_reflection=is_internal_reflection,
        stdmode=stdmode,
    )

    _descend(
        cmd,
        classlayout=classlayout,
        schema=schema,
        context=context,
        blocks=blocks,
        is_internal_reflection=is_internal_reflection,
        stdmode=stdmode,
    )

    mcls = cmd.maybe_get_schema_metaclass()
    if mcls is not None and not issubclass(mcls, so.GlobalObject):
        if isinstance(cmd, s_ref.ReferencedObjectCommand):
            refctx = cmd.get_referrer_context(context)
        else:
            refctx = None

        if (
            refctx is not None
            and mcls.get_reflection_method() is so.ReflectionMethod.AS_LINK
        ):
            refop = refctx.op
            refcls = refop.get_schema_metaclass()
            refdict = refcls.get_refdict_for_class(mcls)

            target_link = mcls.get_reflection_link()
            assert target_link is not None

            target_field = mcls.get_field(target_link)
            target = cmd.get_orig_attribute_value(target_link)

            parent_variables = {}

            parent_variables[f'__{target_link}'] = (
                json.dumps(str(target.get_name(schema)))
            )

            parent_update_query = f'''
                UPDATE schema::{refcls.__name__}
                FILTER .name__internal = <str>$__parent_classname
                SET {{
                    {refdict.attr} -= (
                        SELECT DETACHED (schema::{target_field.type.__name__})
                        FILTER .name__internal = <str>$__{target_link}
                    )
                }}
            '''

            parent_variables['__parent_classname'] = (
                json.dumps(refop.classname)
            )

            blocks.append((parent_update_query, parent_variables))

        query = f'''
            DELETE schema::{mcls.__name__}
            FILTER .name__internal = <str>$__classname;
        '''
        variables = {'__classname': json.dumps(cmd.classname)}
        blocks.append((query, variables))
예제 #2
0
def write_meta_delete_object(
    cmd: sd.DeleteObject,  # type: ignore
    *,
    classlayout: Dict[Type[so.Object], sr_struct.SchemaTypeLayout],
    schema: s_schema.Schema,
    context: sd.CommandContext,
    blocks: List[Tuple[str, Dict[str, Any]]],
    internal_schema_mode: bool,
    stdmode: bool,
) -> None:
    _descend(
        cmd,
        classlayout=classlayout,
        schema=schema,
        context=context,
        blocks=blocks,
        prerequisites=True,
        internal_schema_mode=internal_schema_mode,
        stdmode=stdmode,
    )

    _descend(
        cmd,
        classlayout=classlayout,
        schema=schema,
        context=context,
        blocks=blocks,
        internal_schema_mode=internal_schema_mode,
        stdmode=stdmode,
    )

    mcls = cmd.maybe_get_schema_metaclass()
    if mcls is not None and not issubclass(mcls, so.GlobalObject):
        if isinstance(cmd, s_ref.ReferencedObjectCommand):
            refctx = cmd.get_referrer_context(context)
        else:
            refctx = None

        if (refctx is not None and
                mcls.get_reflection_method() is so.ReflectionMethod.AS_LINK):
            refop = refctx.op
            refcls = refop.get_schema_metaclass()
            refdict = refcls.get_refdict_for_class(mcls)

            target_link = mcls.get_reflection_link()
            assert target_link is not None

            target_field = mcls.get_field(target_link)
            target = cmd.get_orig_attribute_value(target_link)

            parent_variables = {}

            parent_variables[f'__{target_link}'] = (json.dumps(str(target.id)))

            parent_update_query = f'''
                UPDATE schema::{refcls.__name__}
                FILTER .name__internal = <str>$__parent_classname
                SET {{
                    {refdict.attr} -= (
                        SELECT DETACHED (schema::{target_field.type.__name__})
                        FILTER .id = <uuid>$__{target_link}
                    )
                }}
            '''

            ref_name = context.get_referrer_name(refctx)
            parent_variables['__parent_classname'] = (json.dumps(
                str(ref_name)))

            blocks.append((parent_update_query, parent_variables))

        # We need to delete any links created via reflection_proxy
        layout = classlayout[mcls]
        proxy_links = [
            link for link, layout_entry in layout.items()
            if layout_entry.reflection_proxy
        ]

        to_delete = ['D'] + [f'D.{link}' for link in proxy_links]
        operations = [f'(DELETE {x})' for x in to_delete]
        query = f'''
            WITH D := (SELECT schema::{mcls.__name__}
                       FILTER .name__internal = <str>$__classname),
            SELECT {{{", ".join(operations)}}};
        '''
        variables = {'__classname': json.dumps(str(cmd.classname))}
        blocks.append((query, variables))