Esempio n. 1
0
    def test_server_config_02(self):
        storage = immutables.Map()

        op = ops.Operation(ops.OpCode.CONFIG_ADD, config.ConfigScope.INSTANCE,
                           'ports', make_port_value(database='f1'))
        storage1 = op.apply(testspec1, storage)

        op = ops.Operation(ops.OpCode.CONFIG_ADD, config.ConfigScope.INSTANCE,
                           'ports', make_port_value(database='f2'))
        storage2 = op.apply(testspec1, storage1)

        self.assertEqual(
            config.lookup('ports', storage2, spec=testspec1), {
                Port.from_pyvalue(make_port_value(database='f1')),
                Port.from_pyvalue(make_port_value(database='f2')),
            })

        j = ops.to_json(testspec1, storage2)
        storage3 = ops.from_json(testspec1, j)
        self.assertEqual(storage3, storage2)

        op = ops.Operation(ops.OpCode.CONFIG_REM, config.ConfigScope.INSTANCE,
                           'ports', make_port_value(database='f1'))
        storage3 = op.apply(testspec1, storage2)

        self.assertEqual(config.lookup('ports', storage3, spec=testspec1), {
            Port.from_pyvalue(make_port_value(database='f2')),
        })

        op = ops.Operation(ops.OpCode.CONFIG_REM, config.ConfigScope.INSTANCE,
                           'ports', make_port_value(database='f1'))
        storage4 = op.apply(testspec1, storage3)
        self.assertEqual(storage3, storage4)
Esempio n. 2
0
    def test_server_config_04(self):
        storage = immutables.Map()

        op = ops.Operation(ops.OpCode.CONFIG_SET, config.ConfigScope.SESSION,
                           'int', 11)
        storage1 = op.apply(testspec1, storage)
        self.assertEqual(config.lookup('int', storage1, spec=testspec1), 11)

        op = ops.Operation(ops.OpCode.CONFIG_SET, config.ConfigScope.SESSION,
                           'int', '42')
        with self.assertRaisesRegex(errors.ConfigurationError,
                                    "invalid value type for the 'int'"):
            op.apply(testspec1, storage1)

        op = ops.Operation(ops.OpCode.CONFIG_SET, config.ConfigScope.SESSION,
                           'int', 42)
        storage2 = op.apply(testspec1, storage1)

        op = ops.Operation(ops.OpCode.CONFIG_SET, config.ConfigScope.SESSION,
                           'ints', {42})
        storage2 = op.apply(testspec1, storage2)

        op = ops.Operation(ops.OpCode.CONFIG_SET, config.ConfigScope.SESSION,
                           'ints', {42, 43})
        storage2 = op.apply(testspec1, storage2)

        self.assertEqual(config.lookup('int', storage1, spec=testspec1), 11)
        self.assertEqual(config.lookup('int', storage2, spec=testspec1), 42)
        self.assertEqual(config.lookup('ints', storage2, spec=testspec1),
                         {42, 43})
Esempio n. 3
0
    async def init(self):
        self.__sys_pgcon = await self._pg_connect(defines.EDGEDB_SYSTEM_DB)
        await self.__sys_pgcon.set_server(self)
        self._sys_pgcon_waiters = asyncio.Queue()
        self._sys_pgcon_waiters.put_nowait(self.__sys_pgcon)

        await self._load_instance_data()
        await self._load_sys_queries()
        await self._fetch_roles()
        self._dbindex = await dbview.DatabaseIndex.init(self)

        self._populate_sys_auth()

        cfg = self._dbindex.get_sys_config()

        if not self._mgmt_host_addr:
            self._mgmt_host_addr = (
                config.lookup('listen_addresses', cfg) or 'localhost')

        if not self._mgmt_port_no:
            self._mgmt_port_no = (
                config.lookup('listen_port', cfg) or defines.EDGEDB_PORT)

        self._mgmt_port = self._new_port(
            mng_port.ManagementPort,
            nethost=self._mgmt_host_addr,
            netport=self._mgmt_port_no,
            auto_shutdown=self._auto_shutdown,
            max_protocol=self._mgmt_protocol_max,
            startup_script=self._startup_script,
        )
Esempio n. 4
0
    async def init(self):
        self._initing = True
        try:
            self.__sys_pgcon = await self._pg_connect(defines.EDGEDB_SYSTEM_DB)
            self._sys_pgcon_waiter = asyncio.Lock()

            await self._load_instance_data()

            global_schema = await self.introspect_global_schema()
            sys_config = await self.load_sys_config()

            self._dbindex = dbview.DatabaseIndex(
                self,
                std_schema=self._std_schema,
                global_schema=global_schema,
                sys_config=sys_config,
            )

            self._fetch_roles()
            await self._introspect_dbs()

            # Now, once all DBs have been introspected, start listening on
            # any notifications about schema/roles/etc changes.
            await self.__sys_pgcon.set_server(self)

            self._compiler_pool = await compiler_pool.create_compiler_pool(
                pool_size=self._compiler_pool_size,
                dbindex=self._dbindex,
                runstate_dir=self._runstate_dir,
                backend_runtime_params=self.get_backend_runtime_params(),
                std_schema=self._std_schema,
                refl_schema=self._refl_schema,
                schema_class_layout=self._schema_class_layout,
            )

            self._populate_sys_auth()

            if not self._listen_host:
                self._listen_host = (
                    config.lookup('listen_addresses', sys_config)
                    or 'localhost'
                )

            if not self._listen_port:
                self._listen_port = (
                    config.lookup('listen_port', sys_config)
                    or defines.EDGEDB_PORT
                )

            self._http_request_logger = asyncio.create_task(
                self._request_stats_logger()
            )

        finally:
            self._initing = False
Esempio n. 5
0
    def _in_testmode(self, ctx: CompileContext):
        current_tx = ctx.state.current_tx()
        session_config = current_tx.get_session_config()

        return config.lookup(config.get_settings(),
                             '__internal_testmode',
                             session_config,
                             allow_unrecognized=True)
Esempio n. 6
0
    async def init(self):
        self._initing = True
        try:
            self.__sys_pgcon = await self._pg_connect(defines.EDGEDB_SYSTEM_DB)
            self._sys_pgcon_waiter = asyncio.Lock()
            self._sys_pgcon_ready_evt = asyncio.Event()
            self._sys_pgcon_reconnect_evt = asyncio.Event()

            await self._load_instance_data()

            global_schema = await self.introspect_global_schema()
            sys_config = await self.load_sys_config()

            self._dbindex = dbview.DatabaseIndex(
                self,
                std_schema=self._std_schema,
                global_schema=global_schema,
                sys_config=sys_config,
            )

            self._fetch_roles()
            await self._introspect_dbs()

            # Now, once all DBs have been introspected, start listening on
            # any notifications about schema/roles/etc changes.
            await self.__sys_pgcon.listen_for_sysevent()
            self.__sys_pgcon.set_server(self)
            self._sys_pgcon_ready_evt.set()

            self._populate_sys_auth()

            if not self._listen_hosts:
                self._listen_hosts = (config.lookup(
                    'listen_addresses', sys_config) or ('localhost', ))

            if self._listen_port is None:
                self._listen_port = (config.lookup('listen_port', sys_config)
                                     or defines.EDGEDB_PORT)

            self._http_request_logger = asyncio.create_task(
                self._request_stats_logger())

        finally:
            self._initing = False
Esempio n. 7
0
    async def start(self):
        # Make sure that EdgeQL parser is preloaded; edgecon might use
        # it to restore config values.
        ql_parser.preload()

        async with taskgroup.TaskGroup() as g:
            g.create_task(self._mgmt_port.start())
            for port in self._ports:
                g.create_task(port.start())

        sys_config = self._dbindex.get_sys_config()
        ports = config.lookup('ports', sys_config)
        if ports:
            for portconf in ports:
                await self._start_portconf(portconf, suppress_errors=True)

        self._serving = True

        if self._echo_runtime_info:
            ri = {
                "port": self._mgmt_port_no,
                "runstate_dir": str(self._runstate_dir),
            }
            print(f'\nEDGEDB_SERVER_DATA:{json.dumps(ri)}\n', flush=True)
Esempio n. 8
0
 def _populate_sys_auth(self):
     cfg = self._dbindex.get_sys_config()
     auth = config.lookup('auth', cfg) or ()
     self._sys_auth = tuple(sorted(auth, key=lambda a: a.priority))
Esempio n. 9
0
    def _compile_ql_query(self, ctx: CompileContext,
                          ql: qlast.Base) -> dbstate.BaseQuery:

        current_tx = ctx.state.current_tx()
        session_config = current_tx.get_session_config()

        native_out_format = (ctx.output_format is
                             pg_compiler.OutputFormat.NATIVE)

        single_stmt_mode = ctx.stmt_mode is enums.CompileStatementMode.SINGLE

        implicit_fields = (native_out_format and single_stmt_mode)

        disable_constant_folding = config.lookup(config.get_settings(),
                                                 '__internal_no_const_folding',
                                                 session_config,
                                                 allow_unrecognized=True)

        # the capability to execute transaction or session control
        # commands indicates that session mode is available
        session_mode = ctx.state.capability & (enums.Capability.TRANSACTION
                                               | enums.Capability.SESSION)
        ir = ql_compiler.compile_ast_to_ir(
            ql,
            schema=current_tx.get_schema(),
            modaliases=current_tx.get_modaliases(),
            implicit_tid_in_shapes=implicit_fields,
            implicit_id_in_shapes=implicit_fields,
            disable_constant_folding=disable_constant_folding,
            json_parameters=ctx.json_parameters,
            session_mode=session_mode)

        if ir.cardinality is qltypes.Cardinality.ONE:
            result_cardinality = enums.ResultCardinality.ONE
        else:
            result_cardinality = enums.ResultCardinality.MANY
            if ctx.expected_cardinality_one:
                raise errors.ResultCardinalityMismatchError(
                    f'the query has cardinality {result_cardinality} '
                    f'which does not match the expected cardinality ONE')

        sql_text, argmap = pg_compiler.compile_ir_to_sql(
            ir,
            pretty=debug.flags.edgeql_compile,
            expected_cardinality_one=ctx.expected_cardinality_one,
            output_format=ctx.output_format)

        sql_bytes = sql_text.encode(defines.EDGEDB_ENCODING)

        if single_stmt_mode:
            if native_out_format:
                out_type_data, out_type_id = sertypes.TypeSerializer.describe(
                    ir.schema, ir.stype, ir.view_shapes,
                    ir.view_shapes_metadata)
            else:
                out_type_data, out_type_id = \
                    sertypes.TypeSerializer.describe_json()

            in_array_backend_tids: typing.Optional[typing.Mapping[int,
                                                                  int]] = None

            if ir.params:
                array_params = []
                subtypes = [None] * len(ir.params)
                first_param_name = next(iter(ir.params))
                if first_param_name.isdecimal():
                    named = False
                    for param_name, param_type in ir.params.items():
                        idx = int(param_name)
                        subtypes[idx] = (param_name, param_type)
                        if param_type.is_array():
                            el_type = param_type.get_element_type(ir.schema)
                            array_params.append(
                                (idx, el_type.get_backend_id(ir.schema)))
                else:
                    named = True
                    for param_name, param_type in ir.params.items():
                        idx = argmap[param_name] - 1
                        subtypes[idx] = (param_name, param_type)
                        if param_type.is_array():
                            el_type = param_type.get_element_type(ir.schema)
                            array_params.append(
                                (idx, el_type.get_backend_id(ir.schema)))

                params_type = s_types.Tuple.create(
                    ir.schema,
                    element_types=collections.OrderedDict(subtypes),
                    named=named)
                if array_params:
                    in_array_backend_tids = {p[0]: p[1] for p in array_params}
            else:
                params_type = s_types.Tuple.create(ir.schema,
                                                   element_types={},
                                                   named=False)

            in_type_data, in_type_id = sertypes.TypeSerializer.describe(
                ir.schema, params_type, {}, {})

            in_type_args = None
            if ctx.json_parameters:
                in_type_args = [None] * len(argmap)
                for argname, argpos in argmap.items():
                    in_type_args[argpos - 1] = argname

            sql_hash = self._hash_sql(sql_bytes,
                                      mode=str(ctx.output_format).encode(),
                                      intype=in_type_id.bytes,
                                      outtype=out_type_id.bytes)

            return dbstate.Query(
                sql=(sql_bytes, ),
                sql_hash=sql_hash,
                cardinality=result_cardinality,
                in_type_id=in_type_id.bytes,
                in_type_data=in_type_data,
                in_type_args=in_type_args,
                in_array_backend_tids=in_array_backend_tids,
                out_type_id=out_type_id.bytes,
                out_type_data=out_type_data,
            )

        else:
            if ir.params:
                raise errors.QueryError(
                    'EdgeQL script queries cannot accept parameters')

            return dbstate.SimpleQuery(sql=(sql_bytes, ))