mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-28 16:09:17 +00:00
fix(db): support routine rename editing
This commit is contained in:
@@ -113,7 +113,8 @@ test("describes feature support through capability helpers", () => {
|
||||
assert.equal(supportsTableImport("hive"), false);
|
||||
assert.equal(supportsTableStructureEditing("postgres"), true);
|
||||
assert.equal(supportsTableStructureEditing("duckdb"), true);
|
||||
assert.equal(supportsTableStructureEditing("oracle"), false);
|
||||
assert.equal(supportsTableStructureEditing("oracle"), true);
|
||||
assert.equal(supportsTableStructureEditing("dameng"), true);
|
||||
assert.equal(supportsDatabaseCreation("clickhouse"), true);
|
||||
assert.equal(supportsDatabaseCreation("sqlite"), false);
|
||||
assert.equal(supportsFieldLineage("gaussdb"), true);
|
||||
|
||||
@@ -83,6 +83,22 @@ test("builds Oracle-family table and view rename statements", () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("does not build direct Oracle-family routine rename statements", () => {
|
||||
assert.equal(supportsObjectRename("oracle", "FUNCTION"), false);
|
||||
assert.equal(supportsObjectRename("dameng", "PROCEDURE"), false);
|
||||
assert.throws(
|
||||
() =>
|
||||
buildRenameObjectSql({
|
||||
databaseType: "dameng",
|
||||
objectType: "PROCEDURE",
|
||||
schema: "SYSDBA",
|
||||
oldName: "REFRESH_CACHE",
|
||||
newName: "REFRESH_CACHE_V2",
|
||||
}),
|
||||
/Renaming PROCEDURE is not supported/,
|
||||
);
|
||||
});
|
||||
|
||||
test("reports unsupported routine rename cases", () => {
|
||||
assert.equal(supportsObjectRename("mysql", "PROCEDURE"), false);
|
||||
assert.equal(supportsObjectRename("postgres", "FUNCTION"), false);
|
||||
|
||||
@@ -3,7 +3,9 @@ import test from "node:test";
|
||||
import {
|
||||
buildExecutableObjectSourceSql,
|
||||
buildExecutableObjectSourceStatements,
|
||||
buildRoutineRenameObjectSourceStatements,
|
||||
objectSourceSaveExecutionMode,
|
||||
supportsSourceBackedRoutineRename,
|
||||
} from "../../apps/desktop/src/lib/objectSourceEditor.ts";
|
||||
|
||||
test("SQL Server edited source saves as ALTER", () => {
|
||||
@@ -104,3 +106,62 @@ test("object source SQL joins generated save statements for previews", () => {
|
||||
'CREATE OR REPLACE PROCEDURE "public"."refresh_cache_v2"(mode text)\nLANGUAGE SQL\nAS $$ SELECT 1 $$;\nDROP PROCEDURE IF EXISTS "public"."refresh_cache"(mode text);',
|
||||
);
|
||||
});
|
||||
|
||||
test("Oracle and Dameng object source saves as semicolon-terminated source", () => {
|
||||
assert.equal(
|
||||
buildExecutableObjectSourceSql({
|
||||
databaseType: "oracle",
|
||||
objectType: "VIEW",
|
||||
schema: "HR",
|
||||
name: "ACTIVE_USERS",
|
||||
source: "CREATE OR REPLACE VIEW HR.ACTIVE_USERS AS SELECT ID FROM USERS",
|
||||
}),
|
||||
"CREATE OR REPLACE VIEW HR.ACTIVE_USERS AS SELECT ID FROM USERS;",
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
buildExecutableObjectSourceSql({
|
||||
databaseType: "dameng",
|
||||
objectType: "PROCEDURE",
|
||||
schema: "SYSDBA",
|
||||
name: "REFRESH_CACHE",
|
||||
source: "CREATE OR REPLACE PROCEDURE SYSDBA.REFRESH_CACHE AS BEGIN SELECT 1; END;",
|
||||
}),
|
||||
"CREATE OR REPLACE PROCEDURE SYSDBA.REFRESH_CACHE AS BEGIN SELECT 1; END;",
|
||||
);
|
||||
});
|
||||
|
||||
test("MySQL routine rename creates the renamed routine and drops the original routine", () => {
|
||||
const statements = buildExecutableObjectSourceStatements({
|
||||
databaseType: "mysql",
|
||||
objectType: "PROCEDURE",
|
||||
schema: "app",
|
||||
name: "refresh_cache",
|
||||
source: "CREATE DEFINER=`root`@`%` PROCEDURE `refresh_cache_v2`(IN mode_name varchar(20)) BEGIN SELECT 1; END",
|
||||
});
|
||||
|
||||
assert.deepEqual(statements, [
|
||||
"CREATE DEFINER=`root`@`%` PROCEDURE `refresh_cache_v2`(IN mode_name varchar(20)) BEGIN SELECT 1; END;",
|
||||
"DROP PROCEDURE IF EXISTS `app`.`refresh_cache`;",
|
||||
]);
|
||||
});
|
||||
|
||||
test("Oracle-family routine rename rewrites source and drops the original routine", () => {
|
||||
assert.equal(supportsSourceBackedRoutineRename("dameng", "PROCEDURE"), true);
|
||||
assert.equal(supportsSourceBackedRoutineRename("oracle", "FUNCTION"), true);
|
||||
|
||||
const statements = buildRoutineRenameObjectSourceStatements({
|
||||
databaseType: "dameng",
|
||||
objectType: "PROCEDURE",
|
||||
schema: "SYSDBA",
|
||||
name: "SP_TAB_BAKSET_REMOVE_BATCH",
|
||||
newName: "SP_TAB_BAKSET_REMOVE_BATCH_2",
|
||||
source:
|
||||
'CREATE OR REPLACE PROCEDURE "SYSDBA"."SP_TAB_BAKSET_REMOVE_BATCH" AS\nBEGIN\n SELECT 1;\nEND;',
|
||||
});
|
||||
|
||||
assert.deepEqual(statements, [
|
||||
'CREATE OR REPLACE PROCEDURE "SYSDBA"."SP_TAB_BAKSET_REMOVE_BATCH_2" AS\nBEGIN\n SELECT 1;\nEND;',
|
||||
'DROP PROCEDURE "SYSDBA"."SP_TAB_BAKSET_REMOVE_BATCH";',
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -473,3 +473,122 @@ test("index with empty name and columns produces warnings and no statements", ()
|
||||
]);
|
||||
assert.deepEqual(result.statements, []);
|
||||
});
|
||||
|
||||
test("builds Oracle column, comment, and index change statements", () => {
|
||||
const result = buildTableStructureChangeSql({
|
||||
databaseType: "oracle",
|
||||
schema: "HR",
|
||||
tableName: "EMPLOYEES",
|
||||
columns: [
|
||||
column({
|
||||
id: "status",
|
||||
name: "EMP_STATUS",
|
||||
dataType: "VARCHAR2(20)",
|
||||
isNullable: false,
|
||||
defaultValue: "'ACTIVE'",
|
||||
comment: "Employment status",
|
||||
original: {
|
||||
name: "STATUS",
|
||||
data_type: "VARCHAR2(10)",
|
||||
is_nullable: true,
|
||||
column_default: null,
|
||||
is_primary_key: false,
|
||||
extra: null,
|
||||
comment: "",
|
||||
},
|
||||
}),
|
||||
column({ id: "email", name: "EMAIL", dataType: "VARCHAR2(255)", isNullable: true, comment: "Work email" }),
|
||||
column({
|
||||
id: "legacy",
|
||||
name: "LEGACY_CODE",
|
||||
markedForDrop: true,
|
||||
original: {
|
||||
name: "LEGACY_CODE",
|
||||
data_type: "VARCHAR2(20)",
|
||||
is_nullable: true,
|
||||
column_default: null,
|
||||
is_primary_key: false,
|
||||
extra: null,
|
||||
},
|
||||
}),
|
||||
],
|
||||
indexes: [
|
||||
index({
|
||||
id: "old",
|
||||
name: "IDX_EMP_OLD",
|
||||
markedForDrop: true,
|
||||
original: { name: "IDX_EMP_OLD", columns: ["STATUS"], is_unique: false, is_primary: false },
|
||||
}),
|
||||
index({ id: "new", name: "IDX_EMP_STATUS", columns: ["EMP_STATUS"], isUnique: true }),
|
||||
],
|
||||
});
|
||||
|
||||
assert.deepEqual(result.warnings, []);
|
||||
assert.deepEqual(result.statements, [
|
||||
'ALTER TABLE "HR"."EMPLOYEES" RENAME COLUMN "STATUS" TO "EMP_STATUS";',
|
||||
'ALTER TABLE "HR"."EMPLOYEES" MODIFY ("EMP_STATUS" VARCHAR2(20));',
|
||||
'ALTER TABLE "HR"."EMPLOYEES" MODIFY ("EMP_STATUS" NOT NULL);',
|
||||
'ALTER TABLE "HR"."EMPLOYEES" MODIFY ("EMP_STATUS" DEFAULT \'ACTIVE\');',
|
||||
'COMMENT ON COLUMN "HR"."EMPLOYEES"."EMP_STATUS" IS \'Employment status\';',
|
||||
'ALTER TABLE "HR"."EMPLOYEES" ADD ("EMAIL" VARCHAR2(255));',
|
||||
'COMMENT ON COLUMN "HR"."EMPLOYEES"."EMAIL" IS \'Work email\';',
|
||||
'ALTER TABLE "HR"."EMPLOYEES" DROP COLUMN "LEGACY_CODE";',
|
||||
'DROP INDEX "HR"."IDX_EMP_OLD";',
|
||||
'CREATE UNIQUE INDEX "IDX_EMP_STATUS" ON "HR"."EMPLOYEES" ("EMP_STATUS");',
|
||||
]);
|
||||
});
|
||||
|
||||
test("builds Dameng existing column and create table statements", () => {
|
||||
const change = buildTableStructureChangeSql({
|
||||
databaseType: "dameng",
|
||||
schema: "SYSDBA",
|
||||
tableName: "USERS",
|
||||
columns: [
|
||||
column({
|
||||
id: "name",
|
||||
name: "DISPLAY_NAME",
|
||||
dataType: "VARCHAR(120)",
|
||||
isNullable: true,
|
||||
defaultValue: "",
|
||||
comment: "",
|
||||
original: {
|
||||
name: "NAME",
|
||||
data_type: "VARCHAR(80)",
|
||||
is_nullable: false,
|
||||
column_default: "'guest'",
|
||||
is_primary_key: false,
|
||||
extra: null,
|
||||
comment: "Old name",
|
||||
},
|
||||
}),
|
||||
],
|
||||
indexes: [],
|
||||
});
|
||||
|
||||
assert.deepEqual(change.warnings, []);
|
||||
assert.deepEqual(change.statements, [
|
||||
'ALTER TABLE "SYSDBA"."USERS" RENAME COLUMN "NAME" TO "DISPLAY_NAME";',
|
||||
'ALTER TABLE "SYSDBA"."USERS" MODIFY ("DISPLAY_NAME" VARCHAR(120));',
|
||||
'ALTER TABLE "SYSDBA"."USERS" MODIFY ("DISPLAY_NAME" NULL);',
|
||||
'ALTER TABLE "SYSDBA"."USERS" MODIFY ("DISPLAY_NAME" DEFAULT NULL);',
|
||||
'COMMENT ON COLUMN "SYSDBA"."USERS"."DISPLAY_NAME" IS NULL;',
|
||||
]);
|
||||
|
||||
const create = buildCreateTableSql({
|
||||
databaseType: "dameng",
|
||||
schema: "SYSDBA",
|
||||
tableName: "USERS",
|
||||
columns: [
|
||||
column({ id: "id", name: "ID", dataType: "NUMBER", isNullable: false, isPrimaryKey: true }),
|
||||
column({ id: "name", name: "NAME", dataType: "VARCHAR(120)", isNullable: false, comment: "Display name" }),
|
||||
],
|
||||
indexes: [index({ id: "idx", name: "IDX_USERS_NAME", columns: ["NAME"] })],
|
||||
});
|
||||
|
||||
assert.deepEqual(create.warnings, []);
|
||||
assert.deepEqual(create.statements, [
|
||||
'CREATE TABLE "SYSDBA"."USERS" (\n "ID" NUMBER,\n "NAME" VARCHAR(120) NOT NULL,\n PRIMARY KEY ("ID")\n);',
|
||||
'COMMENT ON COLUMN "SYSDBA"."USERS"."NAME" IS \'Display name\';',
|
||||
'CREATE INDEX "IDX_USERS_NAME" ON "SYSDBA"."USERS" ("NAME");',
|
||||
]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user