feat(query): support editing without selected primary keys
This commit is contained in:
11 files changed
+935
-88
No files matched your search
@@ -0,0 +1,98 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildQueryWithHiddenPrimaryKeys, hiddenResultColumnIndexes } from "@/lib/sql/editableQueryHiddenKeys";
|
||||
import { analyzeEditableQueryEditability } from "@/lib/sql/sqlAnalysis";
|
||||
|
||||
describe("editable query hidden primary keys", () => {
|
||||
it("appends quoted MySQL primary keys without changing the visible projection", () => {
|
||||
expect(
|
||||
buildQueryWithHiddenPrimaryKeys({
|
||||
sql: "SELECT name FROM users WHERE active = 1",
|
||||
databaseType: "mysql",
|
||||
primaryKeys: ["id"],
|
||||
existingResultNames: ["name"],
|
||||
}),
|
||||
).toEqual({
|
||||
sql: "SELECT name, `id` AS `__DBX_PK_0` FROM users WHERE active = 1",
|
||||
projections: [{ sourceName: "id", alias: "__DBX_PK_0" }],
|
||||
});
|
||||
});
|
||||
|
||||
it("supports PostgreSQL composite primary keys and avoids alias collisions", () => {
|
||||
const result = buildQueryWithHiddenPrimaryKeys({
|
||||
sql: 'SELECT "value"\nFROM "items"',
|
||||
databaseType: "postgres",
|
||||
primaryKeys: ["tenant_id", "item_id"],
|
||||
existingResultNames: ["value", "__DBX_PK_0"],
|
||||
});
|
||||
|
||||
expect(result?.sql).toBe('SELECT "value", "tenant_id" AS "__DBX_PK_1", "item_id" AS "__DBX_PK_2"\nFROM "items"');
|
||||
expect(result?.projections.map((projection) => projection.alias)).toEqual(["__DBX_PK_1", "__DBX_PK_2"]);
|
||||
});
|
||||
|
||||
it("preserves SQL Server TOP and Oracle optimizer hints", () => {
|
||||
expect(
|
||||
buildQueryWithHiddenPrimaryKeys({
|
||||
sql: "SELECT TOP 10 name FROM dbo.users ORDER BY name",
|
||||
databaseType: "sqlserver",
|
||||
primaryKeys: ["id"],
|
||||
existingResultNames: ["name"],
|
||||
})?.sql,
|
||||
).toBe("SELECT TOP 10 name, [id] AS [__DBX_PK_0] FROM dbo.users ORDER BY name");
|
||||
|
||||
expect(
|
||||
buildQueryWithHiddenPrimaryKeys({
|
||||
sql: "SELECT /*+ INDEX(t IDX_USERS_NAME) */ t.NAME\nFROM USERS t",
|
||||
databaseType: "oracle",
|
||||
primaryKeys: ["ID"],
|
||||
existingResultNames: ["NAME"],
|
||||
})?.sql,
|
||||
).toBe('SELECT /*+ INDEX(t IDX_USERS_NAME) */ t.NAME, "ID" AS "__DBX_PK_0"\nFROM USERS t');
|
||||
});
|
||||
|
||||
it("inserts hidden keys before a trailing line comment", () => {
|
||||
expect(
|
||||
buildQueryWithHiddenPrimaryKeys({
|
||||
sql: "SELECT name -- visible user name\nFROM users",
|
||||
databaseType: "mysql",
|
||||
primaryKeys: ["id"],
|
||||
existingResultNames: ["name"],
|
||||
})?.sql,
|
||||
).toBe("SELECT name, `id` AS `__DBX_PK_0` -- visible user name\nFROM users");
|
||||
});
|
||||
|
||||
it("analyzes SQL Server TOP projections as ordinary source columns", () => {
|
||||
for (const sql of [
|
||||
"SELECT TOP 2 name, note FROM dbo.users ORDER BY name",
|
||||
"SELECT TOP(2) name, note FROM dbo.users ORDER BY name",
|
||||
"SELECT TOP (2) name, note FROM dbo.users ORDER BY name",
|
||||
"SELECT TOP 10 PERCENT name, note FROM dbo.users ORDER BY name",
|
||||
"SELECT TOP (2) WITH TIES name, note FROM dbo.users ORDER BY name",
|
||||
]) {
|
||||
const result = analyzeEditableQueryEditability(sql);
|
||||
expect(result.editable, sql).toBe(true);
|
||||
if (result.editable) expect(result.analysis.columns.map((column) => column.sourceName)).toEqual(["name", "note"]);
|
||||
}
|
||||
});
|
||||
|
||||
it("resolves appended aliases to result indexes", () => {
|
||||
expect(
|
||||
hiddenResultColumnIndexes(
|
||||
["name", "__DBX_PK_0", "__DBX_PK_1"],
|
||||
[
|
||||
{ sourceName: "tenant_id", alias: "__DBX_PK_0" },
|
||||
{ sourceName: "item_id", alias: "__DBX_PK_1" },
|
||||
],
|
||||
),
|
||||
).toEqual([1, 2]);
|
||||
expect(hiddenResultColumnIndexes(["name"], [{ sourceName: "id", alias: "__DBX_PK_0" }])).toEqual([]);
|
||||
expect(
|
||||
hiddenResultColumnIndexes(
|
||||
["name", "__DBX_PK_1"],
|
||||
[
|
||||
{ sourceName: "tenant_id", alias: "__DBX_PK_0" },
|
||||
{ sourceName: "item_id", alias: "__DBX_PK_1" },
|
||||
],
|
||||
),
|
||||
).toEqual([1]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user