Ejemplo n.º 1
0
def write_meta_alter_object(
    cmd: sd.ObjectCommand,  # 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,
    )

    mcls = cmd.maybe_get_schema_metaclass()
    if mcls is not None and not issubclass(mcls, so.GlobalObject):
        shape, variables = _build_object_mutation_shape(
            cmd,
            classlayout=classlayout,
            is_internal_reflection=False,
            stdmode=stdmode,
            schema=schema,
            context=context,
        )

        if shape:
            query = f'''
                UPDATE schema::{mcls.__name__}
                FILTER .name__internal = <str>$__classname
                SET {{
                    {shape}
                }};
            '''
            variables['__classname'] = json.dumps(cmd.classname)
            blocks.append((query, variables))

        if isinstance(cmd, s_ref.ReferencedObjectCommand):
            refctx = cmd.get_referrer_context(context)
            if refctx is not None:
                _update_lprops(
                    cmd,
                    classlayout=classlayout,
                    schema=schema,
                    blocks=blocks,
                    context=context,
                    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,
    )
Ejemplo n.º 2
0
def write_meta_alter_object(
    cmd: sd.ObjectCommand,  # 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,
    )

    mcls = cmd.maybe_get_schema_metaclass()
    if mcls is not None and not issubclass(mcls, so.GlobalObject):
        shape, variables = _build_object_mutation_shape(
            cmd,
            classlayout=classlayout,
            is_internal_reflection=False,
            stdmode=stdmode,
            schema=schema,
            context=context,
        )

        if shape:
            query = f'''
                UPDATE schema::{mcls.__name__}
                FILTER .name__internal = <str>$__classname
                SET {{
                    {shape}
                }};
            '''
            variables['__classname'] = json.dumps(cmd.classname)
            blocks.append((query, variables))

        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)
            layout = classlayout[refcls][refdict.attr]
            lprops = layout.properties

            parent_variables = {}

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

            # XXX: we have to do a -= followed by a += because
            # support for filtered nested link property updates
            # is currently broken.

            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))

            shape, append_variables = _build_object_mutation_shape(
                cmd,
                classlayout=classlayout,
                lprop_fields=lprops,
                lprops_only=True,
                is_internal_reflection=is_internal_reflection,
                stdmode=stdmode,
                schema=schema,
                context=context,
            )

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

            parent_variables.update(append_variables)
            blocks.append((parent_update_query, parent_variables))

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