diff --git a/shared/studio/state/connection.ts b/shared/studio/state/connection.ts index e3abeafe..90b2a0f5 100644 --- a/shared/studio/state/connection.ts +++ b/shared/studio/state/connection.ts @@ -103,11 +103,13 @@ export class Connection extends Model({ }); private _queryQueue: PendingQuery[] = []; + private _baseSessionConfig = Session.defaults(); + @computed get _state() { const sessionState = sessionStateCtx.get(this); - let state = Session.defaults(); + let state = this._baseSessionConfig; if (sessionState?.activeState.globals.length) { state = state.withGlobals( @@ -262,12 +264,26 @@ export class Connection extends Model({ execute: Math.round(executeEndTime - parseEndTime), }; - sessionStateCtx - .get(this)! - .updateGlobalsFromCommand( - statements, - (this.conn as any).lastStateUpdate?.globals - ); + const stateUpdate = (this.conn as any).lastStateUpdate; + if (!opts.ignoreSessionConfig && stateUpdate) { + let newState = Session.defaults(); + if (stateUpdate.module) { + newState = newState.withModuleAliases({module: stateUpdate.module}); + } + if (stateUpdate.aliases) { + newState = newState.withModuleAliases( + (stateUpdate.aliases as [string, string][]).reduce( + (aliases, [key, val]) => { + aliases[key] = val; + return aliases; + }, + {} as {[key: string]: string} + ) + ); + } + this._baseSessionConfig = newState; + sessionStateCtx.get(this)!.updateStateFromCommand(stateUpdate); + } return { result: decode(outCodecBuf, resultBuf, opts.newCodec), diff --git a/shared/studio/state/sessionState.ts b/shared/studio/state/sessionState.ts index cc86c1f0..baef0b0d 100644 --- a/shared/studio/state/sessionState.ts +++ b/shared/studio/state/sessionState.ts @@ -416,22 +416,10 @@ export class SessionState extends Model({ } @modelAction - updateGlobalsFromCommand(statements: string[], stateUpdate: any) { - const globalNames = new Set( - statements - .map( - (statement) => - statement.match(/^\s*(?:re)?set\s+global\s+(.+?)(?:\s|:=|$)/i)?.[1] - ) - .filter((name) => name) as string[] - ); - - if (!globalNames.size) { - return; - } - - console.log(globalNames, stateUpdate); - + updateStateFromCommand(stateUpdate: { + globals?: {[key: string]: any}; + config?: {[key: string]: any}; + }) { const dbState = dbCtx.get(this)!; const schemaDataGlobals = new Map( @@ -441,26 +429,17 @@ export class SessionState extends Model({ ]) ); - for (const globalName of globalNames) { - const type = - schemaDataGlobals.get(globalName) ?? - schemaDataGlobals.get(`default::${globalName}`); - console.log(type); + const unsetGlobals = new Set(); + for (const [globalName, val] of Object.entries( + stateUpdate.globals ?? {} + )) { + const type = schemaDataGlobals.get(globalName); if (!type) { continue; } - const val = stateUpdate?.[type.name]; - if (val === undefined || (val === null && !type.default)) { - const existingGlobalState = this.draftState!.globals[type.name]; - if (existingGlobalState) { - existingGlobalState.active = false; - const [newVal, err] = newPrimitiveValue( - type.target as PrimitiveType - ); - existingGlobalState.value = frozen(newVal); - existingGlobalState.error = err; - } + if (val === null && !type.default) { + unsetGlobals.add(globalName); } else { const editorVal = val != null @@ -475,6 +454,45 @@ export class SessionState extends Model({ }; } } + for (const [globalName, globalState] of Object.entries( + this.draftState!.globals + )) { + if ( + globalState.active && + (unsetGlobals.has(globalName) || !stateUpdate.globals?.[globalName]) + ) { + globalState.active = false; + const [newVal, err] = newPrimitiveValue( + globalState.type.data as PrimitiveType + ); + globalState.value = frozen(newVal); + globalState.error = err; + } + } + + for (const [configName, configState] of Object.entries( + this.draftState!.config + )) { + const val = stateUpdate.config?.[configName]; + if (val === undefined) { + if (configState.active) { + configState.active = false; + const [newVal, err] = newPrimitiveValue( + configState.type.data as PrimitiveType + ); + configState.value = frozen(newVal); + configState.error = err; + } + } else { + configState.active = true; + configState.value = frozen( + val != null + ? valueToEditorValue(val, configState.type.data as PrimitiveType) + : null + ); + configState.error = false; + } + } this.updateActiveState(); this.storeSessionData(); diff --git a/shared/studio/tabs/repl/commands.tsx b/shared/studio/tabs/repl/commands.tsx index d94690ac..7fb4485e 100644 --- a/shared/studio/tabs/repl/commands.tsx +++ b/shared/studio/tabs/repl/commands.tsx @@ -75,6 +75,13 @@ export function renderCommandResult(result: CommandResult) {
\c, \connect DBNAME
Switch to database DBNAME
+
Settings
+ +
\set limit LIMIT
+
+ Set implicit limit to LIMIT. Set to 0 to disable +
+
Help
\?, \h, \help
diff --git a/shared/studio/tabs/repl/state/commands.ts b/shared/studio/tabs/repl/state/commands.ts index 23e9c167..371caf65 100644 --- a/shared/studio/tabs/repl/state/commands.ts +++ b/shared/studio/tabs/repl/state/commands.ts @@ -2,6 +2,7 @@ import {SchemaObjectType, SchemaScalarType} from "@edgedb/common/schemaData"; import {Repl, ReplHistoryItem} from "."; import {dbCtx} from "../../../state"; import {instanceCtx} from "../../../state/instance"; +import {sessionStateCtx} from "../../../state/sessionState"; export enum CommandOutputKind { error, @@ -92,6 +93,50 @@ export async function handleSlashCommand( repl.updateSetting("retroMode", !repl.settings.retroMode); break; } + case "set": { + switch (args[0]) { + case "limit": + const limit = parseInt(args[1], 10); + if (Number.isNaN(limit) || limit < 0) { + item.setCommandResult({ + kind: CommandOutputKind.error, + msg: `invalid limit: '${args[1]}'`, + }); + } else { + item.setCommandResult({kind: CommandOutputKind.none}); + const sessionState = sessionStateCtx.get(repl)!; + const limitState = + sessionState.draftState?.options["Implicit Limit"]; + console.log(sessionState, limitState); + if (limitState) { + if (limit === 0) { + if (limitState.active) { + sessionState.toggleOptionActive("Implicit Limit"); + } + } else { + sessionState.updateItemValue( + limitState, + limit.toString(), + false + ); + if (!limitState.active) { + sessionState.toggleOptionActive("Implicit Limit"); + } + } + sessionState.updateActiveState(); + sessionState.storeSessionData(); + } + } + break; + default: + item.setCommandResult({ + kind: CommandOutputKind.error, + msg: `unknown set command: '${args[0]}'`, + }); + break; + } + break; + } default: item.setCommandResult({ kind: CommandOutputKind.error,