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