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