Esempio n. 1
0
    def run_ddl(cls, schema, ddl, default_module=defines.DEFAULT_MODULE_ALIAS):
        statements = edgeql.parse_block(ddl)

        current_schema = schema
        target_schema = None

        for stmt in statements:
            if isinstance(stmt, qlast.CreateDelta):
                # CREATE MIGRATION
                if target_schema is None:
                    target_schema = _load_std_schema()

                ddl_plan = s_ddl.cmd_from_ddl(
                    stmt,
                    schema=current_schema,
                    modaliases={None: default_module},
                    testmode=True)

                ddl_plan = s_ddl.compile_migration(ddl_plan, target_schema,
                                                   current_schema)

            elif isinstance(stmt, qlast.Delta):
                # APPLY MIGRATION
                delta_cmd = s_ddl.cmd_from_ddl(
                    stmt,
                    schema=current_schema,
                    modaliases={None: default_module},
                    testmode=True)
                delta = current_schema.get(delta_cmd.classname)
                ddl_plan = sd.DeltaRoot(canonical=True)
                ddl_plan.update(delta.get_commands(current_schema))

            elif isinstance(stmt, qlast.DDL):
                # CREATE/DELETE/ALTER (FUNCTION, TYPE, etc)
                ddl_plan = s_ddl.delta_from_ddl(
                    stmt,
                    schema=current_schema,
                    modaliases={None: default_module},
                    testmode=True)

            else:
                raise ValueError(
                    f'unexpected {stmt!r} in compiler setup script')

            context = sd.CommandContext()
            context.testmode = True
            current_schema, _ = ddl_plan.apply(current_schema, context)

        return current_schema
Esempio n. 2
0
    def _assert_migration_consistency(self, schema_text):

        migration_text = f'''
            CREATE MIGRATION m TO {{
                {schema_text}
            }};
        '''

        migration_ql = edgeql.parse_block(migration_text)

        migration_cmd = s_ddl.cmd_from_ddl(
            migration_ql[0],
            schema=self.schema,
            modaliases={None: 'default'},
        )

        migration_cmd = s_ddl.compile_migration(
            migration_cmd,
            self.std_schema,
            self.schema,
        )

        context = s_delta.CommandContext()
        schema, migration = migration_cmd.apply(self.schema, context)

        ddl_plan = s_delta.DeltaRoot(canonical=True)
        ddl_plan.update(migration.get_commands(schema))

        baseline_schema, _ = ddl_plan.apply(schema, context)

        ddl_text = s_ddl.ddl_text_from_delta(schema, migration)

        try:
            test_schema = self.run_ddl(schema, ddl_text)
        except errors.EdgeDBError as e:
            self.fail(markup.dumps(e))

        diff = s_ddl.delta_schemas(baseline_schema, test_schema)

        if list(diff.get_subcommands()):
            self.fail(
                f'unexpected difference in schema produced by\n'
                f'COMMIT MIGRATION and DDL obtained from GET MIGRATION:\n'
                f'{markup.dumps(diff)}\n'
                f'DDL text was:\n{ddl_text}')
Esempio n. 3
0
    def _compile_ql_migration(self, ctx: CompileContext,
                              ql: typing.Union[qlast.Database, qlast.Delta]):
        current_tx = ctx.state.current_tx()
        schema = current_tx.get_schema()

        cmd = s_ddl.cmd_from_ddl(ql,
                                 schema=schema,
                                 modaliases=current_tx.get_modaliases(),
                                 testmode=self._in_testmode(ctx))

        if (isinstance(ql, qlast.CreateDelta)
                and cmd.get_attribute_value('target')):

            if current_tx.is_implicit():
                raise errors.QueryError(
                    f'CREATE MIGRATION must be executed in a '
                    f'transaction block')

            assert self._std_schema is not None
            cmd = s_ddl.compile_migration(cmd, self._std_schema,
                                          current_tx.get_schema())

        return self._compile_command(ctx, cmd)