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
def load_graphql_schema(schema=None): if schema is None: schema = s_schema.Schema() with open(os.path.join(os.path.dirname(__file__), '_graphql.eschema'), 'r') as f: eschema = f.read() script = f''' CREATE MODULE graphql; CREATE MIGRATION graphql::d0 TO eschema $${eschema}$$; COMMIT MIGRATION graphql::d0; ''' statements = edgeql.parse_block(script) for stmt in statements: if isinstance(stmt, qlast.Delta): # CREATE/APPLY MIGRATION ddl_plan = s_ddl.cmd_from_ddl(stmt, schema=schema, modaliases={}) elif isinstance(stmt, qlast.DDL): # CREATE/DELETE/ALTER (FUNCTION, TYPE, etc) ddl_plan = s_ddl.delta_from_ddl(stmt, schema=schema, modaliases={}) context = sd.CommandContext() ddl_plan.apply(schema, context) return schema
async def _run_script(self, script, *, graphql=False, flags={}): timer = Timer() if graphql: with timer.timeit('graphql_translation'): script = graphql_compiler.translate( self.backend.schema, script, variables={}) + ';' with timer.timeit('parse_eql'): statements = edgeql.parse_block(script) results = [] for statement in statements: plan = await planner.plan_statement(statement, self.backend, flags, timer=timer) with timer.timeit('execution'): result = await executor.execute_plan(plan, self) if result is not None and isinstance(result, list): loaded = [] for row in result: if isinstance(row, str): # JSON result row = json.loads(row) loaded.extend(row) else: loaded.append(row) result = loaded results.append(result) return results, timer.as_dict()
async def _load_std(self): schema = s_schema.Schema() current_block = None std_texts = [] for modname in s_schema.STD_LIB + ['stdgraphql']: std_texts.append(s_std.get_std_module_text(modname)) ddl_text = '\n'.join(std_texts) for ddl_cmd in edgeql.parse_block(ddl_text): delta_command = s_ddl.delta_from_ddl( ddl_cmd, schema=schema, modaliases={None: 'std'}, stdmode=True) if debug.flags.delta_plan_input: debug.header('Delta Plan Input') debug.dump(delta_command) # Do a dry-run on test_schema to canonicalize # the schema delta-commands. test_schema = schema context = self.create_context(stdmode=True) canonical_delta = delta_command.copy() canonical_delta.apply(test_schema, context=context) # Apply and adapt delta, build native delta plan, which # will also update the schema. schema, plan = self.process_delta(canonical_delta, schema, stdmode=True) if isinstance(plan, (s_db.CreateDatabase, s_db.DropDatabase)): if (current_block is not None and not isinstance(current_block, dbops.SQLBlock)): raise errors.QueryError( 'cannot mix DATABASE commands with regular DDL ' 'commands in a single block') if current_block is None: current_block = dbops.SQLBlock() else: if (current_block is not None and not isinstance(current_block, dbops.PLTopBlock)): raise errors.QueryError( 'cannot mix DATABASE commands with regular DDL ' 'commands in a single block') if current_block is None: current_block = dbops.PLTopBlock() plan.generate(current_block) sql_text = current_block.to_string() return schema, sql_text
def load_std_schema(): schema = s_schema.Schema() std_eql_f = os.path.join(os.path.dirname(__file__), '_std.eql') with open(std_eql_f) as f: std_eql = f.read() statements = edgeql.parse_block(std_eql) for statement in statements: cmd = s_ddl.delta_from_ddl(statement, schema=schema, modaliases={None: 'std'}) cmd.apply(schema) return schema
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 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
async def _init_std_schema(conn): logger.info('Bootstrapping std module...') stdschema = os.path.join(os.path.dirname(edgedb_schema.__file__), '_std.eql') with open(stdschema, 'r') as f: stdschema_script = f.read() statements = edgeql.parse_block(stdschema_script) bk = await backend.open_database(conn) for statement in statements: cmd = s_ddl.delta_from_ddl(statement, schema=bk.schema, modaliases={None: 'std'}) await bk.run_ddl_command(cmd) await metaschema.generate_views(conn, bk.schema)
def load_default_schema(schema=None): if schema is None: schema = s_schema.Schema() script = f''' CREATE MODULE default; ''' statements = edgeql.parse_block(script) for stmt in statements: if isinstance(stmt, qlast.Delta): # CREATE/APPLY MIGRATION ddl_plan = s_ddl.cmd_from_ddl(stmt, schema=schema, modaliases={}) elif isinstance(stmt, qlast.DDL): # CREATE/DELETE/ALTER (FUNCTION, TYPE, etc) ddl_plan = s_ddl.delta_from_ddl(stmt, schema=schema, modaliases={}) context = sd.CommandContext() ddl_plan.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
def _compile(self, *, ctx: CompileContext, eql: bytes) -> typing.List[dbstate.QueryUnit]: eql = eql.decode() if ctx.graphql_mode: eql = graphql.translate( ctx.state.current_tx().get_schema(), eql, variables={}) + ';' statements = edgeql.parse_block(eql) if ctx.single_query_mode and len(statements) > 1: raise errors.ProtocolError( f'expected one statement, got {len(statements)}') units = [] unit = None txid = None if not ctx.state.current_tx().is_implicit(): txid = ctx.state.current_tx().id for stmt in statements: comp: dbstate.BaseQuery = self._compile_dispatch_ql(ctx, stmt) if ctx.legacy_mode and unit is not None: units.append(unit) unit = None if unit is None: unit = dbstate.QueryUnit(txid=txid, dbver=ctx.state.dbver) if isinstance(comp, dbstate.Query): if ctx.single_query_mode or ctx.legacy_mode: unit.sql = comp.sql unit.sql_hash = comp.sql_hash unit.out_type_data = comp.out_type_data unit.out_type_id = comp.out_type_id unit.in_type_data = comp.in_type_data unit.in_type_id = comp.in_type_id else: unit.sql += comp.sql elif isinstance(comp, dbstate.SimpleQuery): unit.sql += comp.sql elif isinstance(comp, dbstate.DDLQuery): unit.sql += comp.sql unit.has_ddl = True elif isinstance(comp, dbstate.TxControlQuery): unit.sql += comp.sql if comp.action == dbstate.TxAction.START: unit.starts_tx = True unit.txid = txid = ctx.state.current_tx().id else: if comp.action == dbstate.TxAction.COMMIT: unit.commits_tx = True else: unit.rollbacks_tx = True units.append(unit) unit = None elif isinstance(comp, dbstate.SessionStateQuery): unit.config = ctx.state.current_tx().get_config() unit.modaliases = ctx.state.current_tx().get_modaliases() else: raise RuntimeError('unknown compile state') if unit is not None: units.append(unit) return units