Files
openidea/e2e/oracle-source.spec.ts
Budi Santosoandboenkkk 9069c322e8 feat(database): Oracle data source support (#1510)
Adds Oracle as a data source through rust-oracle (ODPI-C), which loads the user's
Oracle Instant Client at runtime; the client is not bundled. The Options tab takes
the Instant Client directory (empty: ORACLE_HOME or the system library path).
Covers connecting, the schema tree, consoles with PL/SQL blocks, table editing,
Generate DDL (DBMS_METADATA), Explain Plan (PLAN_TABLE), Oracle-specific SQL
generation and completion, and jdbc:oracle:thin URLs.

Review fixes: PL/SQL units keep their closing END; (the server rejects a block
without it), a subprogram's declarations no longer split it, and packages end at
a / line; LOB cells are read through locators (they showed as null and broke
Generate DDL); ORA-01005 prompts for a password; the Instant Client directory is
optional in the dialog.

Co-authored-by: boenkkk <17746937+boenkkk@users.noreply.github.com>
2026-11-06 09:57:03 +08:00

46 lines
2.4 KiB
TypeScript

import { expect, test } from "./fixtures";
test("configures an Oracle source with its Instant Client directory", async ({ workbench: page }, info) => {
await page.evaluate(async () => {
const storePath = "/src/features/database/store.ts";
const bindingsPath = "/src/bindings.ts";
const { useDatabase } = await import(storePath);
const { commands } = await import(bindingsPath);
commands.dbTest = async (source: unknown) => {
document.documentElement.dataset.testedSource = JSON.stringify(source);
return { status: "ok", data: "Oracle Database 23ai Enterprise Edition Release 23.5.0.24.07" };
};
useDatabase.setState({ dialog: { kind: "source", source: null } });
});
const dialog = page.getByRole("dialog", { name: "New Data Source", exact: true });
await dialog.getByRole("button", { name: "Data source type", exact: true }).click();
// The type list is virtualised: reach the entry by typing, then confirm it.
await page.keyboard.type("oracle");
await page.keyboard.press("Enter");
await expect(dialog.locator("#db-port")).toHaveValue("1521");
await expect(dialog.locator("#db-url")).toHaveValue("jdbc:oracle://localhost:1521");
// The client libraries are not bundled: the Options tab names their directory (empty: ORACLE_HOME).
const testButton = dialog.getByRole("button", { name: "Test Connection", exact: true });
await dialog.locator("#db-url").fill("oracle://scott:tiger@db.example:1521/ORCLPDB1");
await expect(dialog.locator("#db-host")).toHaveValue("db.example");
await expect(dialog.locator("#db-port")).toHaveValue("1521");
await expect(dialog.locator("#db-user")).toHaveValue("scott");
await expect(dialog.locator("#db-database")).toHaveValue("ORCLPDB1");
await expect(testButton).toBeEnabled();
await dialog.getByRole("tab", { name: "Options", exact: true }).click();
await dialog.locator("#db-instant-client").fill("/opt/oracle/instantclient_23_5");
await testButton.click();
await expect(dialog.getByRole("status")).toHaveText(/^Succeeded: Oracle Database 23ai/);
expect(await page.evaluate(() => JSON.parse(document.documentElement.dataset.testedSource!))).toMatchObject({
driver: "oracle",
host: "db.example",
port: 1521,
user: "scott",
database: "ORCLPDB1",
options: { instantClient: "/opt/oracle/instantclient_23_5" },
});
await dialog.screenshot({ path: info.outputPath("oracle-source-options.png") });
});