This document describes how CL Prompter creates and manages a dedicated SQL job, and how that job is used to execute both:
- CL commands through CMD_RUN
- SQL statements from the Command Entry panel (sql: prefix path)
It also explains how this capability is exposed to other extensions as a supported external API.
- Code for IBM i team
- IBM CLLE extension team
- Extension developers integrating IBM i command and SQL execution patterns
CL Prompter supports two execution modes for Command Entry:
- Shared mode
- Uses the default Code for IBM i connection SQL runner.
- No dedicated CL Prompter-owned SQL job is created.
- Dedicated mode
- Creates and owns a separate Mapepire SQL job.
- Uses that owned job for Command Entry CL and SQL execution paths.
- Keeps dedicated job identity and lifecycle in CL Prompter.
The mode is controlled by setting:
- clPrompter.cmdEntryUseSharedSQLJob
Semantics:
- true: use shared Code for IBM i SQL job
- false: use CL Prompter dedicated SQL job
Owns dedicated job lifecycle and direct SQL execution plumbing.
- Create/reuse/end dedicated Mapepire job
- Maintain dedicated job id and state
- Execute SQL through dedicated job when enabled
- Fallback to connection.runSQL when dedicated mode is disabled
- Cancel active SQL in dedicated mode using:
- CALL QSYS2.CANCEL_SQL(?) via connection.runSQL with bindings
Owns Command Entry execution orchestration.
- Detect sql: statements vs CL command path
- Execute CL command path through CMD_RUN UDTF query
- Execute SQL statement path with chunking/prefetch/session logic
- Delegate low-level SQL execution to CommandEntryJobManager when present
Owns Command Entry UI message routing and feature gating.
- Initializes dedicated job when needed
- Triggers execution through CommandEntryService
- Exposes menu actions like Start New Server Job and Cancel SQL for Server Job
- Disables dedicated-only menu actions when shared mode is active
Owns SQL result rendering and paging/prefetch UX for result sets.
- Command Entry view loads.
- If dedicated mode is enabled, initialization calls restart/create path.
- Job manager obtains Mapepire component from active connection.
- Job manager creates a new job with mapepire.newJob(connection, jdbc options).
- Job manager reads and stores the dedicated job id.
- Later operations reuse that job while connection key matches.
- User runs CL command.
- Service builds CMD_RUN SELECT statement with bindings.
- Service routes SQL execution through job manager.
- In dedicated mode, execution is done on owned dedicated job.
- In shared mode, execution falls back to connection.runSQL.
- User runs statement with sql: prefix.
- Service normalizes statement and applies fetch settings.
- For selectable queries, service uses chunk/prefetch/session paging.
- Chunk fetch calls are routed through job manager execution path.
- Dedicated mode behavior accounts for 100-row backend page behavior by aggregating chunks.
- User chooses Cancel SQL for Server Job from menu.
- View checks dedicated mode capability.
- Job manager uses the stored dedicated job id.
- Job manager sends direct SQL through Code for IBM i API:
- CALL QSYS2.CANCEL_SQL(?)
- bindings: [dedicatedJobId]
No SBMJOB or RUNSQL wrapper is used in the active cancel path.
Use Code for IBM i exported APIs to:
- Get active connection.
- Acquire mapepire component.
- Create and hold your own Mapepire job.
- Route your extension's CL and SQL paths through that owned job.
- Keep fallback path to connection.runSQL for compatibility.
Recommended practical structure:
- Job manager class (own lifecycle, state, cancel)
- Service class (orchestration, chunking, command-vs-sql routing)
- View/controller class (capability gating and UX)
This is now available through the extension export object as multiSqlJob.
Current status: externally accessible.
The activation return object now exposes:
- CLPrompter
- CLPrompterCallback
- multiSqlJob
multiSqlJob is backed by the same shared runtime objects used by Command Entry in this extension (job manager + command service), so external callers and Command Entry operate on the same dedicated/shared mode state.
- CLPrompter
- CLPrompterCallback
- multiSqlJob (apiVersion 1.0.0)
- isDedicatedModeEnabled()
- getJobState()
- ensureDedicatedJob()
- restartDedicatedJob()
- cancelDedicatedJobSql()
- runSql(statements, options)
- getConfig()
- executeCommandEntry(command, mode, executionId?)
- closeSqlSession(sessionId?)
- loadMoreSql(sessionId, fetchAll?, fetchRowsOverride?)
- getConfiguredPrefetchRows()
- Dedicated SQL job creation/reuse/end logic
- Dedicated job id/state retrieval
- Command Entry SQL session and paging internals
- Dedicated-only cancel behavior
- Add contract tests for
multiSqlJobexternal API surface. - Add versioned TypeScript declaration snippet to CLPROMPTER_API.md.
- Add one end-to-end external consumer sample extension.
- Add formal semantic-version compatibility notes for API changes.
- QSYS2.CANCEL_SQL can only cancel interruptible SQL requests.
- It does not cancel arbitrary CL program flow by itself.
- Dedicated mode isolates Command Entry workload from shared SQL runner contention.
- Shared mode remains useful for conservative compatibility and lower state footprint.
If external reuse is a near-term goal, prioritize publishing a minimal sample that consumes multiSqlJob and validates dedicated vs shared behavior in both modes.