Ejemplo n.º 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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
    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()
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
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
Ejemplo n.º 7
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
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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
Ejemplo n.º 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
Ejemplo n.º 11
0
    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