Beispiel #1
0
    def load_schemas(cls):
        script = cls.get_schema_script()
        statements = edgeql.parse_block(script)

        schema = s_std.load_std_schema()
        schema = s_std.load_graphql_schema(schema)

        for stmt in statements:
            if isinstance(stmt, qlast.Delta):
                # CREATE/APPLY MIGRATION
                ddl_plan = s_ddl.cmd_from_ddl(stmt,
                                              schema=schema,
                                              modaliases={None: 'default'})

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

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

            context = sd.CommandContext()
            ddl_plan.apply(schema, context)

        return schema
Beispiel #2
0
    async def run_ddl_command(self, ddl_plan):
        schema = await self.getschema()

        if debug.flags.delta_plan_input:
            debug.header('Delta Plan Input')
            debug.dump(ddl_plan)

        # Do a dry-run on test_schema to canonicalize
        # the schema delta-commands.
        test_schema = await self._intro_mech.readschema()
        context = sd.CommandContext()
        canonical_ddl_plan = ddl_plan.copy()
        canonical_ddl_plan.apply(test_schema, context=context)

        # Apply and adapt delta, build native delta plan, which
        # will also update the schema.
        plan = self.process_delta(canonical_ddl_plan, schema)

        context = delta_cmds.CommandContext(self.connection)

        try:
            if not isinstance(plan, (s_db.CreateDatabase, s_db.DropDatabase)):
                async with self.connection.transaction():
                    # Execute all pgsql/delta commands.
                    await plan.execute(context)
            else:
                await plan.execute(context)
        except Exception as e:
            raise RuntimeError('failed to apply delta to data backend') from e
        finally:
            # Exception or not, re-read the schema from Postgres.
            await self.invalidate_schema_cache()
            await self.getschema()
Beispiel #3
0
    def create_context(self, cmds=None, stdmode=None):
        context = sd.CommandContext()
        context.testmode = self.testmode
        if stdmode is not None:
            context.stdmode = stdmode

        return context
Beispiel #4
0
def delta_from_ddl(stmts,
                   *,
                   schema,
                   modaliases,
                   stdmode: bool = False,
                   testmode: bool = False):
    alter_db = s_delta.DeltaRoot()
    context = s_delta.CommandContext()
    context.modaliases = modaliases
    context.schema = schema
    context.stdmode = stdmode
    context.testmode = testmode

    if isinstance(stmts, edgeql.ast.Base):
        stmts = [stmts]

    for stmt in stmts:
        with context(s_delta.DeltaRootContext(alter_db)):
            alter_db.add(
                cmd_from_ddl(stmt,
                             context=context,
                             schema=schema,
                             modaliases=modaliases,
                             testmode=testmode))

    return alter_db
Beispiel #5
0
    def _new_delta_context(self, ctx: CompileContext):
        current_tx = ctx.state.current_tx()
        config = current_tx.get_config()

        context = s_delta.CommandContext()
        context.testmode = bool(config.get('__internal_testmode'))

        return context
Beispiel #6
0
def cmd_from_ddl(stmt, *, context=None, schema, modaliases):
    # expand module aliases (implicit and explicit)
    ddl = edgeql.deoptimize(stmt, strip_builtins=False)

    if context is None:
        context = s_delta.CommandContext()

    context.modaliases = modaliases
    context.schema = schema

    cmd = s_delta.Command.from_ast(ddl, schema=schema, context=context)
    return cmd
Beispiel #7
0
    def load_delta(self, id, compat_mode=False):
        d = self.read_delta(id, compat_mode=compat_mode)
        if d.script:
            delta_script = edgeql.parse_block(d.script)

            alter_db = s_db.AlterDatabase()
            context = sd.CommandContext()

            with context(s_db.DatabaseCommandContext(alter_db)):
                for ddl in delta_script:
                    ddl = edgeql.deoptimize(ddl)
                    cmd = sd.Command.from_ast(ddl, context=context)
                    alter_db.add(cmd)

            d.deltas = [alter_db]

        return d
Beispiel #8
0
def delta_from_ddl(stmts, *, schema, modaliases):
    alter_db = s_db.AlterDatabase()
    context = s_delta.CommandContext()
    context.modaliases = modaliases
    context.schema = schema

    if isinstance(stmts, edgeql.ast.Base):
        stmts = [stmts]

    for stmt in stmts:
        with context(s_db.DatabaseCommandContext(alter_db)):
            alter_db.add(
                cmd_from_ddl(stmt,
                             context=context,
                             schema=schema,
                             modaliases=modaliases))

    return alter_db
Beispiel #9
0
def load_std_module(schema: s_schema.Schema, modname: str) -> s_schema.Schema:

    modaliases = {}
    if modname == 'std':
        modaliases[None] = 'std'

    context = s_delta.CommandContext()
    context.stdmode = True

    modtext = get_std_module_text(modname)
    for statement in edgeql.parse_block(modtext):
        cmd = s_ddl.delta_from_ddl(statement,
                                   schema=schema,
                                   modaliases=modaliases,
                                   stdmode=True)
        schema, _ = cmd.apply(schema, context)

    return schema
Beispiel #10
0
    def run_ddl(cls, schema, ddl):
        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'})

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

            elif isinstance(stmt, qlast.Delta):
                # APPLY MIGRATION
                ddl_plan = s_ddl.cmd_from_ddl(stmt,
                                              schema=current_schema,
                                              modaliases={None: 'default'})

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

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

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

        return current_schema
Beispiel #11
0
    async def run_delta_command(self, delta_cmd):
        schema = await self.getschema()
        context = sd.CommandContext()
        result = None

        with context(s_deltas.DeltaCommandContext(delta_cmd)):
            if isinstance(delta_cmd, s_deltas.CommitDelta):
                delta = schema.get_delta(delta_cmd.classname)
                ddl_plan = s_db.AlterDatabase()
                ddl_plan.update(delta.commands)
                await self.run_ddl_command(ddl_plan)
                await self._commit_delta(delta, ddl_plan)

            elif isinstance(delta_cmd, s_deltas.GetDelta):
                delta = schema.get_delta(delta_cmd.classname)
                result = s_ddl.ddl_text_from_delta(schema, delta)

            elif isinstance(delta_cmd, s_deltas.CreateDelta):
                delta_cmd.apply(schema, context)

            else:
                raise RuntimeError(f'unexpected delta command: {delta_cmd!r}')

        return result