дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
Run oxfmt once over the whole repository (formatting only, no logic changes) and add `pnpm format:check` to the frontend CI job so unformatted code no longer builds up. `.oxfmtrc.json` now skips the generated theme docs, test fixtures and code blocks inside Markdown. Co-authored-by: jaw52 <[email protected]>
137 рядки
4.9 KiB
TypeScript
137 рядки
4.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { DbColumnInfo } from "@/platform/ipc";
|
|
import {
|
|
alterTableSql,
|
|
createTableSql,
|
|
draftOf,
|
|
dropSql,
|
|
ident,
|
|
reference,
|
|
renameSql,
|
|
scriptSql,
|
|
truncateSql,
|
|
type ColumnDraft,
|
|
} from "./objects";
|
|
|
|
const col = (name: string, dataType: string, extra: Partial<DbColumnInfo> = {}): DbColumnInfo => ({
|
|
name,
|
|
dataType,
|
|
nullable: true,
|
|
default: null,
|
|
primaryKey: false,
|
|
...extra,
|
|
});
|
|
|
|
const users = [
|
|
col("id", "INTEGER", { primaryKey: true, nullable: false }),
|
|
col("email", "TEXT", { nullable: false }),
|
|
col("name", "TEXT"),
|
|
];
|
|
|
|
describe("database object SQL", () => {
|
|
it("quotes only when needed", () => {
|
|
expect(ident("postgres", "users")).toBe("users");
|
|
expect(ident("postgres", "Users")).toBe('"Users"');
|
|
expect(ident("sqlite", "order")).toBe('"order"');
|
|
expect(ident("mysql", "my table")).toBe("`my table`");
|
|
});
|
|
|
|
it("copies references", () => {
|
|
expect(reference("sqlite", { kind: "table", schema: "main", name: "users" })).toBe("users");
|
|
expect(reference("postgres", { kind: "column", schema: "public", name: "users", column: "email" })).toBe(
|
|
"public.users.email",
|
|
);
|
|
});
|
|
|
|
it("renames per dialect", () => {
|
|
expect(renameSql("sqlite", { kind: "table", schema: "main", name: "users" }, "people")).toBe(
|
|
"alter table users rename to people;",
|
|
);
|
|
expect(renameSql("mysql", { kind: "table", schema: "app", name: "users" }, "people")).toBe(
|
|
"rename table app.users to app.people;",
|
|
);
|
|
expect(renameSql("postgres", { kind: "column", schema: "public", name: "users", column: "email" }, "mail")).toBe(
|
|
"alter table public.users rename column email to mail;",
|
|
);
|
|
});
|
|
|
|
it("drops with IF EXISTS / CASCADE", () => {
|
|
const t = { kind: "table" as const, schema: "public", name: "users" };
|
|
expect(dropSql("postgres", t, { ifExists: true, cascade: true })).toBe(
|
|
"drop table if exists public.users cascade;",
|
|
);
|
|
expect(dropSql("sqlite", { ...t, schema: "main" }, { ifExists: false, cascade: true })).toBe("drop table users;");
|
|
expect(
|
|
dropSql(
|
|
"mysql",
|
|
{ kind: "index", schema: "app", name: "ix", table: "users" },
|
|
{ ifExists: false, cascade: false },
|
|
),
|
|
).toBe("drop index ix on app.users;");
|
|
expect(
|
|
dropSql(
|
|
"sqlite",
|
|
{ kind: "column", schema: "main", name: "users", column: "name" },
|
|
{ ifExists: true, cascade: false },
|
|
),
|
|
).toBe("alter table users drop column name;");
|
|
});
|
|
|
|
it("truncates (SQLite deletes)", () => {
|
|
expect(truncateSql("sqlite", "main", "users", { restartIdentity: true, cascade: true })).toBe("delete from users;");
|
|
expect(truncateSql("postgres", "public", "users", { restartIdentity: true, cascade: false })).toBe(
|
|
"truncate table public.users restart identity;",
|
|
);
|
|
});
|
|
|
|
it("writes script templates keyed by the primary key", () => {
|
|
expect(scriptSql("sqlite", "selectFirst", "main", "users", users)).toBe("select *\nfrom users\nlimit 10;\n");
|
|
expect(scriptSql("sqlite", "insert", "main", "users", users)).toBe(
|
|
"insert into users (id, email, name)\nvalues (?, ?, ?);\n",
|
|
);
|
|
expect(scriptSql("sqlite", "update", "main", "users", users)).toBe(
|
|
"update users\nset email = ?,\n name = ?\nwhere id = ?;\n",
|
|
);
|
|
expect(scriptSql("sqlite", "delete", "main", "users", users)).toBe("delete\nfrom users\nwhere id = ?;\n");
|
|
});
|
|
|
|
it("creates tables", () => {
|
|
const drafts: ColumnDraft[] = users.map(draftOf);
|
|
expect(createTableSql("sqlite", "main", "people", drafts)).toBe(
|
|
"create table people\n(\n id INTEGER not null,\n email TEXT not null,\n name TEXT,\n primary key (id)\n);\n",
|
|
);
|
|
});
|
|
|
|
it("alters tables: SQLite renames / adds / drops, PostgreSQL also changes columns", () => {
|
|
const d = users.map(draftOf);
|
|
d[1] = { ...d[1]!, name: "mail" };
|
|
d[2] = { ...d[2]!, dropped: true };
|
|
d.push({
|
|
key: 9,
|
|
original: null,
|
|
name: "age",
|
|
dataType: "INTEGER",
|
|
notNull: false,
|
|
default: "0",
|
|
primaryKey: false,
|
|
dropped: false,
|
|
});
|
|
expect(alterTableSql("sqlite", "main", "users", "people", d)).toEqual([
|
|
"alter table users rename column email to mail;",
|
|
"alter table users drop column name;",
|
|
"alter table users add column age INTEGER default 0;",
|
|
"alter table users rename to people;",
|
|
]);
|
|
const p = users.map(draftOf);
|
|
p[2] = { ...p[2]!, dataType: "varchar(40)", notNull: true, default: "''" };
|
|
expect(alterTableSql("postgres", "public", "users", "users", p)).toEqual([
|
|
"alter table public.users alter column name type varchar(40);",
|
|
"alter table public.users alter column name set not null;",
|
|
"alter table public.users alter column name set default '';",
|
|
]);
|
|
expect(alterTableSql("mysql", "app", "users", "users", p)).toEqual([
|
|
"alter table app.users change column name name varchar(40) default '' not null;",
|
|
]);
|
|
});
|
|
});
|